Cod sursa(job #2468836)

Utilizator Leonard1998Olariu Leonard Leonard1998 Data 6 octombrie 2019 01:11:27
Problema Potrivirea sirurilor Scor 14
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <bits/stdc++.h>
#define MAXLEN (int)(2e6 + 5)
#define d 131

using namespace std;

char pattern[MAXLEN], text[MAXLEN];
int matchCount, matches[MAXLEN];

void rkSearch(char pat[], char txt[], int q) {
    int pLen = strlen(pat);
    int nLen = strlen(txt);
    int i, j;

    int h = 1; //value of h would be pow(d, pLen-1) % q
    for (i = 0; i < pLen - 1; ++i)
        h = (h * d) % q;

    //calculate the hash value of pattern and first window of text
    int pHash = 0, tHash = 0;
    for (i = 0; i < pLen; i++) {
        pHash = (d * pHash + pat[i]) % q;
        tHash = (d * tHash + txt[i]) % q;
    }

    //slide the pattern over text one by one
    for (i = 0; i <= nLen - pLen; ++i) {
        //check the hash values of current window of text and pattern
        //if the hash values match then only check for characters on by one
        if (pHash == tHash) {
            //check for characters one by one
            for (j = 0; j < pLen; j++)
                if (txt[i+j] != pat[j])
                    break;

            //if p == t and pat[0...pLen-1] = txt[i, i+1, ...i + pLen-1]
            if (j == pLen)
                matches[++matchCount] = i;
        }

        //calculate hash value for next window of text
        //remove leading digit, add trailing digit
        if (i < nLen - pLen) {
            tHash = (d * (tHash - txt[i]*h) + txt[i + pLen]) % q;

            //we might get negative value of t
            //we should convert it to positive
            if (tHash < 0)
                tHash += q;
        }
    }
}

int main()
{
    freopen("strmatch.in", "r", stdin);
    freopen("strmatch.out", "w", stdout);

    scanf("%s %s", pattern, text);
    rkSearch(pattern, text, (int)(1e9 + 7));

    printf("%d\n", matchCount);
    int minOut = min(matchCount, 1000);
    for (int i = 1; i <= minOut; ++i)
        printf("%d ", matches[i]);
    printf("\n");

    return 0;
}