Cod sursa(job #3294871)

Utilizator stefan05Vasilache Stefan stefan05 Data 29 aprilie 2025 22:52:56
Problema Potrivirea sirurilor Scor 38
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.92 kb
//KMP
#include <fstream>
#include <cstring>

#define SMAX 2000005

using namespace std;

ifstream fin("strmatch.in");
ofstream fout("strmatch.out");

char pattern[SMAX];
char s[SMAX];
int f[SMAX];
int rez[SMAX]; int nr;
int k, i;

int main()
{
    fin >> pattern >> s;
    int m = strlen(pattern);
    int n = strlen(s);

    //aflare (cu i = 0..m) f[i] = prefix maxim pentru pattern[0..i-1] astfel incat acesta e si sufix
    f[0] = -1;
    for (i = 1; i <= m; ++i)
    {
        k = f[i - 1];
        while (k >= 0 && pattern[k] != pattern[i - 1]) //cat timp nu am gasit un prefix la [0..i-1] cat mai mare, la care sa putem pune ultima litera necesara(pattern[i-1]) (prefixul lui [0...i-1] extinde mereu prefixul lui [0...i-2] cu pattern[i-1])
            k = f[k];
        if (k == -1)
            f[i] = 0;
        else
            f[i] = k + 1;
    }

    //calculare kmp (pattern matching)
    int i = 0, k = 0; //i este pozitia curenta la care cautam pattern, k este cat prefix din pattern stim deja ca e matched
    while (i < n - m) //cat timp mai pot gasi pattern (i < n-m), si nu am gasit inca (k < m)
    {
        if (k == m)
        {
            rez[++nr] = i;
            i = i + k - f[k];
            k = f[k];
        }
        if (s[i + k] == pattern[k])
            k++; //am mai gasit o litera ca parte din matching prefix
        else
            if (k == 0)
                i++; //daca nu exista prefix nevid matching, trecem la urmatoarea pozitie, nu avem ce face
            else
                {   
                    i = i + k - f[k]; //nu am gasit pattern perfect, trec mai departe, sar direct la ultimele f[k]
                    k = f[k];
                }
    }

    fout << nr << '\n';
    for (i = 1; i <= min(nr, 1000); ++i)
        fout << rez[i] << ' ';
    fout << '\n';
    //if (k == m)
    //    //succes
    //else
    //    //failure
    return 0;
}