Mai intai trebuie sa te autentifici.
Cod sursa(job #1457308)
| Utilizator | Data | 3 iulie 2015 09:18:21 | |
|---|---|---|---|
| Problema | Potrivirea sirurilor | Scor | 100 |
| Compilator | cpp | Status | done |
| Runda | Arhiva educationala | Marime | 2.19 kb |
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
///// DESCRIPTION
// THIS PROGRAM FINDS ALL OCCURENCES
// OF STRING A IN STRING B BY USING
// THE RABIN-KARP ALGORITHM AND AVOIDS
// COLLISIONS BY COMPARING 2 HASHES
/////
// !!! the MAXN number might be too big for
// the stack of variables in main for local compilers
const int MAXN = 2000001; // max number of chars
const int base = 256; // number of characters
// to avoid collisions, the hash is calculated 2x
// by using 2 different prime numbers for modulo
const int mod_prime1 = 100007; // big-enough prime number
const int mod_prime2 = 100021; // big-enough prime number
int main()
{
// INPUT
ifstream indata("strmatch.in");
char A[MAXN], B[MAXN];
indata >> A >> B;
indata.close();
// PATTERN MATCHING
vector<int> positions;
int m = strlen(A), n = strlen(B);
// calculate hashes for pattern
// and for first substring
int baseToPow1 = 1, baseToPow2 = 1;
int hashA1 = 0, hashA2 = 0;
int hashB_last1 = 0, hashB_last2 = 0;
for (int i = 0; i < m; i++) {
hashA1 = (hashA1 * base + A[i]) % mod_prime1;
hashA2 = (hashA2 * base + A[i]) % mod_prime2;
hashB_last1 = (hashB_last1 * base + B[i]) % mod_prime1;
hashB_last2 = (hashB_last2 * base + B[i]) % mod_prime2;
if (i != 0) {
baseToPow1 = (baseToPow1 * base) % mod_prime1;
baseToPow2 = (baseToPow2 * base) % mod_prime2;
}
}
// check where the hashes match
if (hashB_last1 == hashA1 && hashB_last2 == hashA2) {
positions.push_back(0);
}
for (int i = m; i < n; i++)
{
// (a % b + b) % b -- this is how to get correct modulo value even for negative values of a, e.g. -3 mod 5 = 2
hashB_last1 = ((hashB_last1 - (B[i - m] * baseToPow1) % mod_prime1 + mod_prime1) * base + B[i]) % mod_prime1;
hashB_last2 = ((hashB_last2 - (B[i - m] * baseToPow2) % mod_prime2 + mod_prime2) * base + B[i]) % mod_prime2;
if (hashB_last1 == hashA1 && hashB_last2 == hashA2) {
positions.push_back(i - m + 1);
}
}
// OUTPUT
ofstream outdata("strmatch.out");
outdata << positions.size() << "\n";
for (size_t i = 0; i < positions.size() && i < 1000; i++) {
outdata << positions[i] << " ";
}
outdata.close();
return 0;
}