Cod sursa(job #906864)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 7 martie 2013 12:25:08
Problema Potrivirea sirurilor Scor 14
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include<fstream>
#include<cstring>
#include<cmath>
#define MOD1 100003
#define MOD2 300007
#define H 17
using namespace std;
int n,m,Pi[2000005],nrsol,sol[1005];
char T[2000005],P[2000005];
 
inline void Citire()
{
    ifstream fin("strmatch.in");
    fin>>(P+1);
    fin>>(T+1);
    fin.close();
    n=strlen(T+1);
    m=strlen(P+1);
}
 
inline void KMP()
{
    int i,k=0;
    Pi[1]=0;
	for(i=2;i<=m;i++)
	{
		while(k && P[k+1]!=P[i]) k=Pi[k];
		if(P[k+1]==P[i]) k++;
		Pi[i]=k;
	}
	k=0;
    for(i=1;i<=n;i++)
    {
        while(k && P[k+1]!=T[i]) k=Pi[k];
        if(P[k+1]==T[i]) k++; //s-au potrivit
        if(k==m) //am gasit intreg pattern-ul
        {
            nrsol++;
            if(nrsol<=1000)
                sol[nrsol]=i-m;
            k=Pi[k];
        }
    }
}

inline void Rabin_Karp()
{
	int i,rez1=0,rez2=0,p=1,now1=0,now2=0;
	for(i=1;i<=m;i++)
	{
		rez1=(rez1*H+P[i])%MOD1;
		rez2=(rez2*H+P[i])%MOD2;
		if(i<m)
			p=(p*H)%MOD1;
	}
	if(n<m)
		return;
	for(i=1;i<=m;i++)
	{
		now1=(now1*H+T[i])%MOD1;
		now2=(now2*H+T[i])%MOD2;
	}
	if(now1==rez1 && now2==rez2)
	{
		nrsol++;
		sol[nrsol]=0;
	}
	for(i=m+1;i<=n;i++)
	{
		now1=((now1-(p*T[i-m])%MOD1+MOD1)*H+T[i])%MOD1;
		now2=((now2-(p*T[i-m])%MOD2+MOD2)*H+T[i])%MOD2;
		if(now1==rez1 && now2==rez2 && nrsol<1000)
		{
			nrsol++;
			sol[nrsol]=i-m;
		}
	}
}

inline void Afisare()
{
    int i,lim;
    lim=min(nrsol,1000);
    ofstream fout("strmatch.out");
    fout<<nrsol<<"\n";
    for(i=1;i<=lim;i++)
        fout<<sol[i]<<' ';
    fout<<"\n";
    fout.close();
}
 
int main()
{
    Citire();
    //KMP();
	Rabin_Karp();
    Afisare();
    return 0;
}