Cod sursa(job #2999234)

Utilizator CalinHanguCalinHangu CalinHangu Data 10 martie 2023 18:19:02
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

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


const int MAXLENGTH = 2000005;
const int HASH_SIZE = 666013;
const int HASH_BASE = 256;
const char nl = '\n';

char str[MAXLENGTH], pattern[MAXLENGTH];
int strLength, patternLength, f[MAXLENGTH];

int lgput(int a, int n, int mod){
    int p = 1;
    while(n){
        if(n & 1)
            p = (long long)p * a % mod;
        a = (long long)a * a % mod;
        n >>= 1;
    }
    return p;
}

bool cmp(char str[], char pattern[]){
    int i = 0;
    while(str[i] && pattern[i] && str[i] == pattern[i])
        ++i;
    if(pattern[i] == 0)
        return true;
    return false;
}

int computeHash(char str[], int length)
{
    int code = 0, i = 0;
    while(i < length){
        code = (code * HASH_BASE + str[i]) % HASH_SIZE;
        ++i;
    }
    return code;
}

int addToHash(int code, char ch){
    return(code * HASH_BASE + ch) % HASH_SIZE;
}

int removeFromHash(int code, char ch, int power)
{
    code = code - ch * power % HASH_SIZE;
    if(code < 0)
        code += HASH_SIZE;
    return code;
}

void search(char str[], int strLength, char pattern[], int patternLength){
    int i, patternHash, strHash, power, cnt = 0;
    patternHash = computeHash(pattern, patternLength);
    strHash = computeHash(str, patternLength - 1);

    power = lgput(HASH_BASE, patternLength - 1, HASH_SIZE);
    bool patternFound = false;
    i = patternLength;
    while(i <= strLength){
        //cout << i << " " << strLength << nl;
        strHash = addToHash(strHash, str[i - 1]);
        if(patternHash == strHash && cmp(str + i - patternLength, pattern)){
            f[i - patternLength] = 1;
            cnt++;
            patternFound = true;
        }
        else
            patternFound = false;
        strHash = removeFromHash(strHash, str[i - patternLength], power);
        ++i;
    }
    out << cnt << nl;
    cnt = 0;
    for(int i = 0; i <= strLength && cnt < 1000; ++i){
        if(f[i]){
            cnt++;
            out << i << ' ';
        }
    }
}

int main()
{
    in.getline(pattern, MAXLENGTH);
    patternLength = strlen(pattern);

    in.getline(str, MAXLENGTH);
    strLength = strlen(str);
    search(str, strLength, pattern, patternLength);
    return 0;
}