Cod sursa(job #784449)

Utilizator f.v.antonFlavius Anton f.v.anton Data 5 septembrie 2012 19:30:42
Problema Potrivirea sirurilor Scor 36
Compilator c Status done
Runda Arhiva educationala Marime 1.41 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LMAX 2000002

void shift(char *str, int n)
{
	int i;
	for (i = n; i > 0; i--)
		str[i] = str[i-1];
}

int* compute_prefix(char *P, int m)
{
	int q, k = 0, *f = calloc(m+1, sizeof(int));
	
	for (q = 2; q <= m; q++) {
		while (k > 0 && P[k+1] != P[q])
			k = f[k];

		if (P[k+1] == P[q])
			k++;

		f[q] = k;
	}
	
	return f;
}

int* KMP(char *T, char *P, int n, int m, int *num_app)
{
	int i, *f, q = 0, *app = malloc(1001 * sizeof(char));
	*num_app = 0;

	f = compute_prefix(P, m);

	for (i = 1; i <= n; i++) {
		while (q > 0 && P[q+1] != T[i])
			q = f[q];

		if (P[q+1] == T[i])
			q++;

		if (q == m) {
			if (*num_app < 1000)
				app[*num_app] = i - m;
			(*num_app)++;
			q = f[q];
		}
	}
	free(f);
	return app;
}

void print(FILE *g, int *app, int num_app)
{
	int i;
	fprintf(g, "%d\n", num_app);

	if (num_app > 1000)
		num_app = 1000;

	for (i = 0; i < num_app; i++)
		fprintf(g, "%d ", app[i]);
}

int main(void)
{
	FILE *f, *g;
	char *T = NULL, *P = NULL;
	int *app = NULL;
	int n, m, num_app;

	f = fopen("strmatch.in", "rt");
	g = fopen("strmatch.out", "wt");
	T = malloc(LMAX * sizeof(char));
	P = malloc(LMAX * sizeof(char));

	fscanf(f, "%s", P);
	fscanf(f, "%s", T);

	n = strlen(T);
	m = strlen(P);

	shift(T, n);
	shift(P, m);

	app = KMP(T, P, n, m, &num_app);
	print(g, app, num_app);

	fclose(f);
	fclose(g);
	
	free(T);
	free(P);
	free(app);
	return 0;
}