Cod sursa(job #3208732)

Utilizator DarnAndrei Nedelcu Darn Data 29 februarie 2024 16:50:16
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
// https://www.infoarena.ro/problema/strmatch
// Check all occurances of string a in b
//
// Other sources:
// https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm


#include <fstream>
#include <vector>

using namespace std;

vector<int> getKmpTable(string a)
{
    vector<int> t(a.length() + 1);
    t[0] = -1;
    int candidate = 0;
    int i = 1;
    for (; i < a.length(); i++, candidate++)
    {
        if (a[i] == a[candidate])
        {
            t[i] = t[candidate];
        }
        else
        {
            t[i] = candidate;
            while (candidate >= 0 && a[i] != a[candidate])
                candidate = t[candidate];
        }
    }
    t[i] = candidate;

    return t;
}

vector<int> getMatches(string a, string b, vector<int>& kmpTable)
{
    int i = 0, k = 0;
    int lenA = a.length();
    int lenB = b.length();
    vector<int> matches;

    while (i < lenB)
    {
        if (a[k] == b[i])
        {
            i++;
            k++;
            if (k == lenA)
            {
                matches.push_back(i-lenA);
                k = kmpTable[k];
            }
        }
        else
        {
            k = kmpTable[k];
            if (k < 0)
            {
                i++;
                k++;
            }
        }
    }

    return matches;
}

int main()
{
    ifstream fin("strmatch.in");
    string a, b;
    fin >> a >> b;
    fin.close();

    auto kmpTable = getKmpTable(a);
    auto matches = getMatches(a,b,kmpTable);

    ofstream fout("strmatch.out");
    fout << matches.size() << "\n";
    for (int i = 0; i < matches.size() && i < 1000; i++)
        fout << matches[i] << " ";
    fout.close();
}