Cod sursa(job #487693)

Utilizator iraIrina Stanescu ira Data 26 septembrie 2010 00:46:40
Problema Potrivirea sirurilor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.31 kb
#include <stdio.h>
#include <string.h>

#define infile "strmatch.in"
#define outfile "strmatch.out"

#define NMAX 2000000

//#define DEBUG 1

char m[NMAX], n[NMAX];
int pi[NMAX], match[NMAX];
int lenm, lenn, tot;

void read_data() {
	FILE *fin = fopen(infile, "r");

	fscanf(fin, "%s", m);
	fscanf(fin, "%s", n);	

	lenm = strlen(m);
	lenn = strlen(n);

#ifdef DEBUG
	printf("%s\n", m);
	printf("%s\n", n);
#endif
	
	fclose(fin);
}


void calc_pi() {
	
	int x, i;

	pi[0] = -1;
	x = -1;
	
	for (i = 1; i < lenm ; i++) {
		
		while (m[x + 1] != m[i] && x > -1) {
			x = pi[x];
		}
		
		if (m[x + 1] == m [i]) {
			x++;
		}
		
		pi[i] = x;
	}

#ifdef DEBUG
	for (i = 0; i < lenm; i++) {
		printf("%d ", pi[i]);
	}
	printf("\n");
#endif 
}



void kmp() {

	int x, j;

	x = 0;

	for (j = 0; j < lenn; j++) { 

		while (m[x] != n[j] && x > 0) {
			x = pi[x - 1] + 1;
		} 

		if (m[x] == n[j]) {
			x++;
		}

		if (x == lenm) {
			match[tot++] = j -lenm + 1;
#ifdef DEBUG
			printf("potrivire la pozitia %d\n",j - lenm + 1);
#endif
		}
	}

}

void write_data() {

	int i;
	FILE *fout = fopen(outfile, "w");
	fprintf(fout, "%d\n", tot);

	if (tot > 1000)
		tot = 1000;

	for (i = 0; i < tot; i++) {
		fprintf(fout, "%d ", match[i]);
	}
	fprintf(fout, "\n");

	fclose(fout);
}


int main() {

	read_data();
	calc_pi();
	kmp();
	write_data();	
}