Pagini recente » Cod sursa (job #2260193) | Cod sursa (job #3268787) | Cod sursa (job #3279378) | Cod sursa (job #234522) | Cod sursa (job #1833185)
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
static const int MAX_LENGTH = 2000001;
enum StringMatcherType {
KNUTH_MORRIS_PRATT,
RABIN_KARP,
BRUTE_FORCE,
};
class StringMatcher {
public:
StringMatcher(char *needle, char *haystack) : needle(needle), haystack(haystack) { }
virtual ~StringMatcher() { }
virtual vector<int> findMatches() = 0;
protected:
char* needle;
char* haystack;
};
class KMP : public StringMatcher {
private:
void buildPrefix(const char* string, const int& length, int* prefix)
{
int index = 0;
prefix[0] = 0;
for (int i = 1; i < length; ) {
if (string[i] == string[index]) {
prefix[i] = index + 1;
index++;
i++;
} else {
if (index != 0) {
index = prefix[index - 1];
} else {
prefix[i] = 0;
i++;
}
}
}
}
public:
vector<int> findMatches() override {
int needleLength = strlen(needle);
int haystackLength = strlen(haystack);
int *prefix = new int[needleLength];
buildPrefix(needle, needleLength, prefix);
int index = 0;
vector<int> solutions;
for (int i = 0; i < haystackLength; ) {
if (haystack[i] == needle[index]) {
index++;
i++;
if (index == needleLength) {
solutions.push_back(i - needleLength);
index = prefix[index - 1];
}
} else {
if (index != 0) {
index = prefix[index - 1];
} else {
i++;
}
}
}
delete prefix;
return solutions;
}
public:
KMP(char *needle, char *haystack) : StringMatcher(needle, haystack) { }
};
class StringMatcherFactory {
private:
StringMatcherFactory() { }
static StringMatcherFactory *instance;
char* needle;
char* haystack;
public:
static StringMatcherFactory* getInstance() {
if (StringMatcherFactory::instance == nullptr) {
StringMatcherFactory::instance = new StringMatcherFactory();
}
return StringMatcherFactory::instance;
}
void setNeedle(char *needle) {
this->needle = needle;
}
void setHaystack(char *haystack) {
this->haystack = haystack;
}
StringMatcher* getMatcher(StringMatcherType type) {
switch (type) {
case KNUTH_MORRIS_PRATT:
return new KMP(needle, haystack);
default:
return nullptr;
}
}
};
StringMatcherFactory* StringMatcherFactory::instance = nullptr;
int main() {
ifstream in("strmatch.in");
ofstream out("strmatch.out");
char *needle, *haystack;
needle = new char[MAX_LENGTH];
haystack = new char[MAX_LENGTH];
in.getline(needle, MAX_LENGTH);
in.getline(haystack, MAX_LENGTH);
StringMatcherFactory* factory = StringMatcherFactory::getInstance();
factory->setHaystack(haystack);
factory->setNeedle(needle);
StringMatcher* kmpSolver = factory->getMatcher(KNUTH_MORRIS_PRATT);
vector<int> solutions = kmpSolver->findMatches();
out << solutions.size() << "\n";
int show = min((int) solutions.size(), 1000);
for (int i = 0; i < show; i++) {
out << solutions[i] << " ";
}
delete needle;
delete haystack;
delete kmpSolver;
in.close();
out.close();
return 0;
}