Pagini recente » Arhiva de probleme | Cod sursa (job #3290757) | Cod sursa (job #3293460) | Arhiva de probleme | Cod sursa (job #3294876)
//KMP
#include <fstream>
#include <cstring>
#define SMAX 2000005
using namespace std;
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
char pattern[SMAX];
char s[SMAX];
int f[SMAX];
int rez[SMAX]; int nr;
int k, i;
int main()
{
fin >> pattern >> s;
int m = strlen(pattern);
int n = strlen(s);
//aflare (cu i = 0..m) f[i] = prefix maxim pentru pattern[0..i-1] astfel incat acesta e si sufix
f[0] = -1;
for (i = 1; i <= m; ++i)
{
k = f[i - 1];
while (k >= 0 && pattern[k] != pattern[i - 1]) //cat timp nu am gasit un prefix la [0..i-1] cat mai mare, la care sa putem pune ultima litera necesara(pattern[i-1]) (prefixul lui [0...i-1] extinde mereu prefixul lui [0...i-2] cu pattern[i-1])
k = f[k];
if (k == -1)
f[i] = 0;
else
f[i] = k + 1;
}
//calculare kmp (pattern matching)
int i = 0, k = 0; //i este pozitia curenta la care cautam pattern, k este cat prefix din pattern stim deja ca e matched
while (i < n - m) //cat timp mai pot gasi pattern (i < n-m), si nu am gasit inca (k < m)
{
if (s[i + k] == pattern[k])
{
k++; //am mai gasit o litera ca parte din matching prefix
if (k == m)
{
rez[++nr] = i;
i = i + k - f[k];
k = f[k];
}
}
else
if (k == 0)
i++; //daca nu exista prefix nevid matching, trecem la urmatoarea pozitie, nu avem ce face
else
{
i = i + k - f[k]; //nu am gasit pattern perfect, trec mai departe, sar direct la ultimele f[k]
k = f[k];
}
}
fout << nr << '\n';
for (i = 1; i <= min(nr, 1000); ++i)
fout << rez[i] << ' ';
fout << '\n';
//if (k == m)
// //succes
//else
// //failure
return 0;
}