Cod sursa(job #1911706)

Utilizator radu.leonardoThe Doctor radu.leonardo Data 7 martie 2017 21:30:32
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <bits/stdc++.h>
using namespace std;

int pi[2000001];
unsigned int pos[1000], n, m, nr;
string a, b;


void read()
{
    ifstream f("strmatch.in");
    getline(f, a);
    getline(f, b);
    n = a.size();
    m = b.size();
    f.close();
}

void build_prefix_table()
{
    unsigned int wPos = 2, cnd = 0;
    pi[0] = -1;
    pi[1] = 0;

    while (wPos < n)
    {
        if (a[wPos - 1] == a[cnd])
        {
            cnd++;
            pi[wPos] = cnd;
            wPos++;
        }
        else
            if (cnd > 0)
            {
                cnd = pi[cnd];
            }
            else
            {
                pi[wPos] = 0;
                wPos++;
            }
    }
}

void kmp_search()
{
    int matchPos = 0, wordPos = 0;

    while (matchPos + wordPos < m)
    {
        if (a[wordPos] == b[matchPos + wordPos])
        {

            if (wordPos == n - 1)
            {
                if (++nr <= 1000) pos[nr - 1] = matchPos;

                if (pi[wordPos] > -1)
                {
                    matchPos+= wordPos-pi[wordPos];//shift
                    wordPos = pi[wordPos];
                }
                else wordPos = 0,matchPos++;

            }
            else wordPos++;
        }
        else
            if (pi[wordPos] > -1)
                {
                    matchPos+= wordPos-pi[wordPos];//shift
                    wordPos = pi[wordPos];
                }
                else wordPos = 0,matchPos++;
    }
}

void write()
{
    ofstream g("strmatch.out");
    g<<nr<<"\n";
    for (int i = 0; i < (nr < 1000 ? nr : 1000); i++)   g << pos[i] << " ";

    g.close();
}

int main()
{
    read();
    build_prefix_table();
    kmp_search();
    write();
}