Pagini recente » Clasamentul arhivei de probleme | Rating Linca Mihaela Amalia (Linca_Amalia) | Cod sursa (job #3298012) | Cod sursa (job #3184212) | Cod sursa (job #3300557)
#include <fstream>
#include <algorithm>
#include <cstring>
using namespace std;
ifstream cin("strmatch.in");
ofstream cout("strmatch.out");
const int NMAX=2*1e6+5;
const int SMAX=265;
int f[NMAX], g[NMAX], h[NMAX], gs[NMAX];
int bc[SMAX], ans[1005];
char p[NMAX], t[NMAX];
void pref(char * p, int m, int f[])
{
int i, k;
f[0]=-1;
for(i=1; i<=m; i++)
{
k=f[i-1];
while(k>=0 && p[k]!=p[i-1]) k=f[k];
f[i]=k+1;
}
}
void bad_chars(char *p)
{
int i;
for(i=0; i<256; i++) bc[i]=-1;
for(i=0; p[i]; i++) bc[p[i]]=i;
}
void good_sufs(char *p, int m)
{
pref(p, m, f);
int i;
for(i=0; p[i]; i++) gs[i]=f[m]-(m-i);
reverse(p, p+m);
pref(p, m, h);
for(i=0; i<=m; i++) g[i]=h[m-i];
for(i=0; i<=m; i++) gs[m-g[i]]=i;
reverse(p, p+m);
}
void bm(char *t, int n, char *p, int m)
{
int i=0, k=0, cnt=0;
bad_chars(p);
good_sufs(p, m);
while(i<=(n-m))
{
if(t[i+m-k-1]==p[m-k-1])
{
k++;
if(k==m)
{
cnt++;
if(cnt<=1000) ans[cnt]=i;
i+=m-f[m];
k=0;
}
}
else
{
int shiftbc=m-k-1-bc[t[i+m-k-1]];
int shiftgs=m-k-gs[m-k];
i+=max(shiftbc, shiftgs);
k=0;
}
}
cout<<cnt<<'\n';
for(i=1; i<=min(cnt, 1000); i++) cout<<ans[i]<<' ';
}
int main()
{
cin>>p>>t;
bm(t, strlen(t), p, strlen(p));
return 0;
}