Cod sursa(job #1561462)

Utilizator alexandru92alexandru alexandru92 Data 4 ianuarie 2016 09:26:27
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <string>
#include <array>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>


const int ALPHA = 67;
const int MOD1 = 100043;
const int MOD2 = 105137;
const int MAX_MATCHES_TO_PRINT = 1000;

std::pair<int, std::vector<int>> strMatch(const std::string& p, const std::string& s) {
    if (p.size() > s.size()) {
        return std::make_pair(0, std::vector<int>{});
    }
    else if (p.size() == s.size()) {
       if (p == s) {
           return std::make_pair(1, std::vector<int>{0});
       } 
       else {
           return std::make_pair(0, std::vector<int>{});
       }
    }

    std::vector<int> matches;
    matches.reserve(MAX_MATCHES_TO_PRINT);

    int numMatches = 0;
    int hashP1 = 0, hashP2 = 0, H1 = 1, H2 = 1, hash1 = 0, hash2 = 0;
    for (size_t i = 0; i < p.size(); ++i) {
        hashP1 = (hashP1 * ALPHA + p[i]) % MOD1;
        hashP2 = (hashP2 * ALPHA + p[i]) % MOD2;

        hash1 = (hash1 * ALPHA + s[i]) % MOD1;
        hash2 = (hash2 * ALPHA + s[i]) % MOD2;

        if (i) {
            H1 = (H1 * ALPHA) % MOD1;
            H2 = (H2 * ALPHA) % MOD2;
        }
    }

    if (hash1 == hashP1 && hash2 == hashP2) {
        matches.push_back(0);
        ++numMatches;
    }

    for (auto i = p.size(); i < s.size(); ++i) {
        hash1 = (((hash1 - s[i - p.size()] * H1) % MOD1 + MOD1) * ALPHA + s[i]) % MOD1;
        hash2 = (((hash2 - s[i - p.size()] * H2) % MOD2 + MOD2) * ALPHA + s[i]) % MOD2;

        if (hash1 == hashP1 && hash2 == hashP2) {
            ++numMatches;
            if (MAX_MATCHES_TO_PRINT > matches.size()) {
                matches.push_back(i - p.size() + 1);
            }
        }
    }

    return std::make_pair(numMatches, matches);
}

int main() {
    std::string p, s;
    std::ifstream in{"strmatch.in"};
    std::ofstream out{"strmatch.out"};
    
    in >> p >> s;

    const auto& x = strMatch(p, s);

    out << x.first << '\n';
    std::copy(x.second.begin(), x.second.end(), std::ostream_iterator<int>{out, " "});

    return 0;
}