Pagini recente » Cod sursa (job #3133327) | Cod sursa (job #2062011) | Cod sursa (job #2122919) | Cod sursa (job #2342733) | Cod sursa (job #1875908)
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
ifstream in("strmatch.in");
ofstream out("strmatch.out");
const int NMax = 2000000 + 5;
char patt[NMax],str[NMax];
int pf[NMax],sol[NMax];
int nrSol,lenPatt,lenStr;
// patt - sirul sablon care este cautat
// str - sirul in care se cauta
// pf = functia de prefix,
// pf[i] = cel mai mare prefix al sablonului care este si sufix
// al prefixului de lungime i al sablonului (cu exceptia prefixului de lungime i in sine)
// EX. :
// pentru sirul abacabadabacaba
// pf[15] = 7, deoarece abacaba este prefix al sirului, dar si sufix pentru prefixul de lungime 15
void build_prefixFunction();
void matchStrings();
int main() {
in.getline(patt+1,NMax - 3);
in.getline(str+1,NMax - 3);
lenPatt = strlen(patt+1);
lenStr = strlen(str+1);
if (lenPatt>lenStr) {
out<<0;
return 0;
}
build_prefixFunction();
matchStrings();
out<<nrSol<<'\n';
nrSol = (nrSol>1000) ? 1000 : nrSol;
for (int i=1;i<=nrSol;++i) {
out<<(sol[i]-1)<<' ';
}
in.close();out.close();
return 0;
}
void build_prefixFunction() {
int k=0;
pf[0]=0;
for (int i=2;i<=lenPatt;++i) {
while (patt[i]!=patt[k+1] && k>0) {
k = pf[k];
}
if (patt[i]==patt[k+1]) {
++k;
}
pf[i]=k;
}
}
void matchStrings() {
int k=0;
for (int i=1;i<=lenStr;++i) {
// daca se gaseste un mismatch, se incearca folosirea unui prefix al subsirului care a fost egal pana in i-1
// in loc sa se reia cautarea de la primul element din pattern de fiecare data
while (str[i]!=patt[k+1] && k>0) {
k = pf[k];
}
if (str[i]==patt[k+1]) {
++k;
if (k==lenPatt) {
sol[++nrSol] = i-lenPatt+1;
k = pf[k];
}
}
}
}