Cod sursa(job #2675168)

Utilizator AntoniuFicAntoniu Ficard AntoniuFic Data 21 noiembrie 2020 10:49:22
Problema Potrivirea sirurilor Scor 14
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
#define n1 9153637
#define n2 9231329
#define a1 31
#define a2 37

using namespace std;

class rollingHash{
private: unsigned long long key;
        unsigned long long maxpower;
        unsigned long long n;
public:
    unsigned long long val;
    bool operator== (const rollingHash &other) const {
        return (this->val == other.val);
    }
    void assignKeys(int key, int n){
        this->key = key;
        this->n = n;
    }
    void buildInitialHash(string x){
        this->val = 0;
        unsigned long long p = 1;
        for (int i = x.length() - 1; i >= 0; --i) {
            this->val = (this->val + ((p * x[i]) % this->n)) % this->n;
            this->maxpower = p;
            p = (p * this->key) % this->n;
        }
    }
    void rollHash(char out, char in){
        this->val = ((this->val - out * this->maxpower) * this->key + in) % this->n;
    }
};

int main() {
    ifstream f("strmatch.in");
    ofstream g("strmatch.out");
    string a, b;
    f>>a>>b;
    rollingHash h1a, h2a;
    h1a.assignKeys(a1, n1);
    h2a.assignKeys(a2, n2);
    h1a.buildInitialHash(a);
    h2a.buildInitialHash(a);
    vector<int> matches;
    rollingHash h1b, h2b;
    h1b.assignKeys(a1, n1);
    h2b.assignKeys(a2, n2);
    h1b.buildInitialHash(b.substr(0, a.length()));
    h2b.buildInitialHash(b.substr(0, a.length()));
    for (int i = a.length(); i < b.length(); ++i) {
        if(h1a == h1b && h2a == h2b) matches.push_back(i - a.length());
        h1b.rollHash(b[i - a.length()], b[i]);
        h2b.rollHash(b[i - a.length()], b[i]);
    }
    if(h1a == h1b && h2a == h2b) matches.push_back(b.length() - a.length());
    g<<matches.size()<<'\n';
    int l = matches.size();
    if(1000 < matches.size())
        l = 1000;
    for (int i = 0; i < l; ++i) {
        g<<matches[i]<<' ';
    }
    return 0;
}