Cod sursa(job #1267885)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 20 noiembrie 2014 13:59:50
Problema Potrivirea sirurilor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.57 kb
//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;
}