Pagini recente » Cod sursa (job #2640655) | Cod sursa (job #457682) | Cod sursa (job #2650535) | Cod sursa (job #2532339) | Cod sursa (job #149316)
Cod sursa(job #149316)
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
const int Factor = 73;
const int Mod1 = 100007;
const int Mod2 = 100021;
char P[2000002],
T[2000002];
int matched[1001],
mn(0);
int M,
N;
FILE *fout;
void rkmatch() {
int ps1(0),
ps2(0);
for (int i(0); i < M; ++i) {
ps1 = (ps1 * Factor + P[i]) % Mod1;
ps2 = (ps2 * Factor + P[i]) % Mod2;
}
//cout << ps1 << " - " << ps2 << endl;
int raisedFactor1(1),
raisedFactor2(1);
for (int i(0); i < M - 1; ++i) {
raisedFactor1 = (raisedFactor1 * Factor) % Mod1;
raisedFactor2 = (raisedFactor2 * Factor) % Mod2;
}
int check1(0),
check2(0);
int i(0);
for (; i < M; ++i) {
check1 = (check1 * Factor + T[i]) % Mod1;
check2 = (check2 * Factor + T[i]) % Mod2;
}
if ((check1 == ps1) && (check2 == ps2))
matched[mn++] = 0;
for (; i < N; ++i) {
check1 = ((check1 - (T[i-M]*raisedFactor1) % Mod1 + Mod1) * Factor + T[i]) % Mod1;
check2 = ((check2 - (T[i-M]*raisedFactor2) % Mod2 + Mod2) * Factor + T[i]) % Mod2;
//cout << check1 << " - " << check2 << endl;
if ((check1 == ps1) && (check2 == ps2))
if (mn < 1000)
matched[mn++] = i - M + 1;
else
++mn;
/*if (check1 == ps1) {
for (int j(0); j < M; ++j)
if (P[j] != T[i - M + 1 + j])
continue;
matched[mn++] = i - M + 1;
}*/
}
fprintf(fout, "%d\n", mn);
for (i = 0; i < ((mn > 1000) ? (1000) : (mn)); ++i)
fprintf(fout, "%d ", matched[i]);
fprintf(fout, "\n");
}
void bmmatch() {
int d[256];
for (int i(0); i < 256; ++i)
d[i] = M;
for (int i(0); i < M - 1; ++i)
d[(int)P[i]] = M - i - 1;
int i = M,
j,
k;
do {
j = M;
k = i;
do {
--k;
--j;
} while ((j >= 0) && (P[j] == T[k]));
if (j < 0)
if (mn < 1000)
matched[mn++] = k + 1;
else
++mn;
i += d[(int)T[i - 1]];
} while (i <= N);
fprintf(fout, "%d\n", mn);
for (i = 0; i < ((mn > 1000) ? (1000) : (mn)); ++i)
fprintf(fout, "%d ", matched[i]);
fprintf(fout, "\n");
}
int d[2000002];
void kmpmatch() {
int j = 0,
k = -1;
d[0] = -1;
while (j < M - 1) {
while ((k >= 0) && (P[j] != P[k]))
k = d[k];
++j;
++k;
if (P[j] == P[k])
d[j] = d[k];
else
d[j] = k;
}
/* for (int i(0); i < M; ++i)
cout << P[i] << " ";
cout << endl;
for (int i(0); i < M; ++i)
cout << d[i] << " ";
cout << endl;*/
int i = j = k = 0;
while (i < N) {
while ((j >= 0) && (T[i] != P[j]))
j = d[j];
++i;
++j;
if (j == M) {
if (mn < 1000)
matched[mn++] = i - M;
else
++mn;
j = 0;
i = i - M + 1;
}
}
fprintf(fout, "%d\n", mn);
for (i = 0; i < ((mn > 1000) ? (1000) : (mn)); ++i)
fprintf(fout, "%d ", matched[i]);
fprintf(fout, "\n");
}
int main(int argc, char *argv[]) {
FILE *fin = fopen("strmatch.in", "r");
fscanf(fin, "%s", P);
fscanf(fin, "%s", T);
fclose(fin);
fout = fopen("strmatch.out", "w");
M = strlen(P);
N = strlen(T);
if (M > N) {
fprintf(fout, "0\n");
} else {
//rkmatch();
//bmmatch();
kmpmatch();
}
fclose(fout);
return 0;
}