Pagini recente » Cod sursa (job #377874) | Cod sursa (job #1371378) | Cod sursa (job #561174) | Cod sursa (job #1935615) | Cod sursa (job #1267885)
//KMP O(M+N)
//precalculez pi[i]=lungimea celui mai lung prefix din a care se potriveste cu caracterele i-pi[i]+1, i-pi[i]+2, ..., i
#include <stdio.h>
#define MAXN 2000000
#define MAXM 2000000
#define MAXS 1000
int pi[MAXM+1], v[MAXS+1], m, n;
char a[MAXM+1], b[MAXN+1];
FILE *fin, *fout;
inline void citire(char v[], int *k){
char ch;
(*k)=0;
ch=fgetc(fin);
while(ch!='\n'){
v[++(*k)]=ch;
ch=fgetc(fin);
}
}
inline void precalc(){
int i, r;
pi[1]=0;
for(i=2; i<=m; i++){
r=pi[i-1];
while((r!=0)&&(a[r+1]!=a[i])){
r=pi[r];
}
if(a[r+1]==a[i]){
pi[i]=r+1;
}else{
pi[i]=0;
}
}
}
inline void potrivirile(){
int nrsol, r, i;
nrsol=0;
r=0;
for(i=1; i<=n; i++){
while((r!=0)&&(a[r+1]!=b[i])){
r=pi[r];
}
if(a[r+1]==b[i]){
r++;
}
if(r==m){//potrivire pe i-m+1...i
nrsol++;
if(nrsol<=MAXS){
v[nrsol]=i-m;
}
}
}
fprintf(fout, "%d\n", nrsol);
if(nrsol>MAXS){
nrsol=MAXS;
}
for(i=1; i<nrsol; i++){
fprintf(fout, "%d ", v[i]);
}
if(nrsol>0){
fprintf(fout, "%d\n", v[nrsol]);
}
}
int main(){
fin=fopen("strmatch.in", "r");
fout=fopen("strmatch.out", "w");
citire(a, &m);//O(m)
citire(b, &n);//O(n)
precalc();//O(m)
potrivirile();//O(n+m)
fclose(fin);
fclose(fout);
return 0;
}