Cod sursa(job #2773331)

Utilizator andcovAndrei Covaci andcov Data 6 septembrie 2021 15:42:35
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
//
// Created by Andrei Covaci on 03.09.2021.
//

//#include "005_strmatch.h"

#include <fstream>
#include <vector>

using namespace std;

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

const int BASE = 73;
const int PRIME_MODULUS_ONE = 100007;
const int PRIME_MODULUS_TWO = 100021;
int OFFSET_ONE = 1;
int OFFSET_TWO = 1;

pair<string, string> read() {
    pair<string, string> res;
    getline(in, res.first);
    getline(in, res.second);
    return res;
}

int hasher_one(string s) {
    int hash = s[0];
    for(int i = 1; i < s.size(); ++i) {
        hash *= BASE;
        hash %= PRIME_MODULUS_ONE;
        hash += s[i];
        hash %= PRIME_MODULUS_ONE;
    }

    return hash;
}

int hasher_two(string s) {
    int hash = s[0];
    for(int i = 1; i < s.size(); ++i) {
        hash *= BASE;
        hash %= PRIME_MODULUS_TWO;
        hash += s[i];
        hash %= PRIME_MODULUS_TWO;
    }

    return hash;
}

void calc_offsets(int size) {
    for(int i = 0; i < size - 1; ++i) {
        OFFSET_ONE %= PRIME_MODULUS_ONE;
        OFFSET_ONE *= BASE;
    }
    for(int i = 0; i < size - 1; ++i) {
        OFFSET_TWO %= PRIME_MODULUS_TWO;
        OFFSET_TWO *= BASE;
    }
}

vector<int> solve(pair<string, string> strings) {
    string pattern = strings.first, s = strings.second;

    if(pattern.size() > s.size()) {
        return vector<int>();
    }

    calc_offsets(pattern.size());

    auto pattern_hash_one = hasher_one(pattern);
    auto pattern_hash_two = hasher_two(pattern);

    auto curr_hash_one = hasher_one(s.substr(0, pattern.size()));
    auto curr_hash_two = hasher_two(s.substr(0, pattern.size()));

    vector<int> pos;


    for(int i = 0; i <= s.size() - pattern.size(); ++i) {
        if (pattern_hash_one == curr_hash_one && pattern_hash_two == curr_hash_two) {
            pos.push_back(i);
        }

        curr_hash_one = ((curr_hash_one + PRIME_MODULUS_ONE - s[i] * OFFSET_ONE % PRIME_MODULUS_ONE) * BASE + s[i + pattern.size()]) % PRIME_MODULUS_ONE;
        curr_hash_two = ((curr_hash_two + PRIME_MODULUS_TWO - s[i] * OFFSET_TWO % PRIME_MODULUS_TWO) * BASE + s[i + pattern.size()]) % PRIME_MODULUS_TWO;
    }

    return pos;
}

void print(vector<int> res) {
    out << res.size() << '\n';
    for(int i = 0; i < 1000 && i < res.size(); ++i) {
        out << res[i] << ' ';
    }
}

int main() {
    auto nums = read();
    auto res = solve(nums);
    print(res);


    return 0;
}