Pagini recente » Cod sursa (job #2442700) | Cod sursa (job #1356706) | Cod sursa (job #2300115) | Cod sursa (job #2828280) | Cod sursa (job #2444867)
#include <iostream>
#include <fstream>
#include <cstring>
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
#define MAX_N 2000005
#define MAX_COUNT 1000
//---------------------------------------------------------------------------
unsigned length, n, countMatches;
char pattern[MAX_N + 2];
char str[MAX_N + 2];
unsigned matches[MAX_COUNT + 1];
unsigned psi[MAX_N + 2];
//---------------------------------------------------------------------------
void compressPi()
// compress pi[] and create two new arrays: psi[] and omega[]
// description in README
{
// Initialize the first values
// 0 is the first state. At this step it receives 2 sons
psi[0] = 0;
psi[1] = 0;
// Compute pi and psi
unsigned k = 0;
for (unsigned q = 1; q < length; ++q) {
// Compute psi
while ((k > 0) && (pattern[q] != pattern[k])) {
k = psi[k];
}
if (pattern[q] == pattern[k]) {
k++;
}
// Compress possible path
// For understandability reasons, keep the formula like this
// TODO: it could be replaced by: (pattern[q + 1] == pattern[k]) ? psi[k] : k
psi[q + 1] = (pattern[q + 1] == pattern[k]) ? psi[k] : k;
}
}
//---------------------------------------------------------------------------
void search()
// checks if the pattern can be found in str
{
if (length > n)
return;
unsigned q = 0; // current state
for (unsigned index = 0; index < n; ++index) {
// Search only on psi now
while ((q > 0) && (str[index] != pattern[q]))
q = psi[q];
if (str[index] == pattern[q]) {
++q;
}
// Found?
if (q == length) {
if ((++countMatches) <= MAX_COUNT) {
matches[countMatches - 1] = index - length + 1;
}
}
}
}
//---------------------------------------------------------------------------
int main(int argv, char** argc) {
#if 0
std::ifstream in(argc[1]);
#else
std::ifstream in("strmatch.in");
#endif
in >> pattern >> str;
in.close();
length = strlen(pattern);
n = strlen(str);
cerr << length << " " << n << endl;
compressPi();
search();
std::ofstream out("strmatch.out");
out << countMatches << endl;
unsigned lim = (countMatches < MAX_COUNT) ? countMatches : MAX_COUNT;
for (unsigned index = 0; index < lim; ++index)
out << matches[index] << " ";
out << endl;
out.close();
return 0;
}