Cod sursa(job #2872303)

Utilizator RobertuRobert Udrea Robertu Data 16 martie 2022 19:26:19
Problema Potrivirea sirurilor Scor 18
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
/*
Incercare de a rezolva pb 'strmatch' de pe infoarena
folosind algoritmul KMP.
*/

#include <bits/stdc++.h>
#include <string>
using namespace std;

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

void prefix(string word, vector<int>& prefix);
void KMP(string word, string pattern, vector<int>& prefix, vector<int>& potriviri, int& cnt);

int main() {
    int cnt = 0;
    string cuv, pat;
    vector<int> p;
    vector<int> potriviri;

    fin >> pat >> cuv;
    prefix(pat, p);
    KMP(cuv, pat, p, potriviri, cnt);

    fout << cnt << endl;
    for(int i = 0; i < min(cnt, 1000); i++)
        fout << potriviri[i] << " ";
    

    return 0;
}


void KMP(string word, string pattern, vector<int>& prefix, vector<int>& potriviri, int &cnt) {
    int m = word.length(), n = pattern.length();
    int j = 0, i = 0;

    //cu i iteram in 'word' iar cu j iteram in 'pattern'
    
    for(; i < m; i++) {
        while(j > 0 && word[i] != pattern[j])
            j = prefix[j - 1];

        if( word[i] == pattern[j] )
            j++;

        if( j == n ) {
            // cout << "Potrivire la poz " << i - n + 1 << endl;
            if(cnt <= 1000)
                potriviri.push_back(i - n + 1);
            cnt++;
            j = 0;
            i--;
        }
    } 
}


/*
Funtia pentru a contrui vectorul in care tin
pozitiile pentru prefix

Complexitate: O(n)
*/
void prefix(string word, vector<int>& prefix) {
    int n = word.length(), j = 0, i = 1;
    prefix.resize(n, 0);
    prefix[j] = 0;

    for(; i < n; i++) {
        while( j > 0 && word[i] != word[j] )
            j = prefix[j - 1];

        if( word[j] == word[i] ) {
            prefix[i] = j + 1;
            j++;
        }
    }
}