Cod sursa(job #302712)

Utilizator whiskeyOzzy Osbourne whiskey Data 9 aprilie 2009 10:37:34
Problema Potrivirea sirurilor Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <cstdio>
const int MAXN = 2000010;

int n, m, nr_aparitii;
char sir1[MAXN];
char sir2[MAXN];
int pi[MAXN];
int aparitii[1010];

void read();
void write();
void prefix();
void prefix2();
void kmp();

int main()
{
	read();
	prefix();
	kmp();
	write();
	return 0;
}

void kmp()
{
	nr_aparitii = 0;
	int i, q = 0;
	for (i = 1; i <= n; ++i)
	{
		while (q > 0 && sir1[q+1] != sir2[i])
		{
			q = pi[q];
		}
		if (sir1[q + 1] == sir2[i])
		{
			++q;
		}
		if (q == m)
		{
			if (nr_aparitii < 1000)
			{
				aparitii[++nr_aparitii] = i - m;
			}
			else
			{
				++nr_aparitii;
			}
			q = pi[q];
		}
	}
}

void prefix()
{
	int k = 0, q;
	pi[1] = 0;
	for (q = 2; q <= m; ++q)
	{
		while (k > 0 && sir1[k+1] != sir1[q])
		{
			k = pi[k];
		}
		if (sir1[k+1] == sir1[q])
		{
			++k;
		}
		pi[q] = k;
	}
}

void prefix2()
{
	int i, j, k;
	pi[1] = 0;
	for (i = 2; i <= m; ++i)
	{
		k = i - 1;
		loop:
		{
			for (j = 1; j <= k; ++j)
			{
				if (sir1[j] != sir1[j+i-k])
				{
					--k;
					goto loop;
				}
			}
		}
		pi[i] = k;
	}

}

void read()
{
	FILE *fin = fopen("strmatch.in", "r");
	fgets(sir1 + 1, MAXN - 1, fin);
	fgets(sir2 + 1, MAXN - 1, fin);
	fclose(fin);
	for (m = 1; sir1[m] != '\n'; ++m);
	for (n = 1; sir2[n] != '\n'; ++n);
	--m;
	--n;
}

void write()
{
	int i, k = (nr_aparitii <= 1000 ? nr_aparitii : 1000);
	FILE *fout = fopen("strmatch.out", "w");
	fprintf(fout, "%d\n", nr_aparitii);
	for (i = 1; i <= k; ++i)
	{
		fprintf(fout, "%d ", aparitii[i]);
	}
	fprintf(fout, "\n");
	fclose(fout);
	for (i = 1; i <= m; ++i)
	{
		printf("%d ", pi[i]);
	}
}