Cod sursa(job #2388354)

Utilizator AkrielAkriel Akriel Data 25 martie 2019 22:33:24
Problema Potrivirea sirurilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

string text;
string pattern;

const int base = 256;
const int prime1 = 100007;
const int prime2 = 100021;

int computeHash(string text, int length, const int prime){
    int hash = 0;
    for (int index = 0; index < length; index++){
        hash *= 256;
        int letter = text[index];
        hash += letter;
        hash %= prime;
    }

    if (hash < 0)
        hash += prime;

    return hash;
}

int nextHash(long long hash, int newPos, string text, int length, const int prime){

    const long long offSet = (((base%prime)*base)%prime);

    int oldPos = newPos-length;
    hash += prime;

    hash -= text[oldPos]*offSet;

    hash *= base;

    hash += text[newPos];

    hash %= prime;

    if (hash < 0)
        hash += prime;

    return hash;
}

vector <int> matches;

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

int main() {
    fin >> pattern;
    fin >> text;

    if (pattern.size() > text.size()){
        cout << 0;
        return 0;
    }

    int patternHash1 = computeHash(pattern, pattern.size(), prime1);
    int patternHash2 = computeHash(pattern, pattern.size(), prime2);

    int currentHash1 = computeHash(text, pattern.size(), prime1);
    int currentHash2 = computeHash(text, pattern.size(), prime2);

    if (patternHash1 == currentHash1 and patternHash2 == currentHash2)
        matches.push_back(0);

    for (int index = pattern.size(); index < text.size(); index++){
        currentHash1 = nextHash(currentHash1, index, text, pattern.size(), prime1);
        currentHash2 = nextHash(currentHash2, index, text, pattern.size(), prime2);

        if (patternHash1 == currentHash1 and patternHash2 == currentHash2){
            int start = index-pattern.size()+1;
            matches.push_back(start);
        }
    }

    fout << matches.size() << "\n";
    int index = 0;
    for (auto it : matches){
        fout << it << " ";
        if (index == 1000)
            break;
    }
}