Pagini recente » Cod sursa (job #167933) | Cod sursa (job #2766566) | Cod sursa (job #1229060) | Cod sursa (job #1505169) | Cod sursa (job #473516)
Cod sursa(job #473516)
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class PatternMatcher{
public:
static vector<int> kmpSearch(const string& text, const string& pattern);
private:
static vector<int> computeKmpPrefix(const string& pattern);
PatternMatcher();
PatternMatcher(const PatternMatcher&);
const PatternMatcher& operator=(const PatternMatcher&);
};
vector<int> PatternMatcher::computeKmpPrefix(const std::string &pattern){
int patternSize = pattern.size();
vector<int> kmpPrefix(patternSize);
size_t prefixPos = 0;
size_t suffixPos = 1;
while(suffixPos < patternSize){
if(pattern[prefixPos] == pattern[suffixPos]){
kmpPrefix[suffixPos] = prefixPos + 1;
prefixPos++;
suffixPos++;
}
else if(prefixPos > 0){//found some match
prefixPos = kmpPrefix[prefixPos -1];//backtrack for matching prefix e.g. aaaaabaaaaaa
}
else{
kmpPrefix[suffixPos] = 0;
suffixPos++;
}
}
return kmpPrefix;
}
vector<int> PatternMatcher::kmpSearch(const std::string &text, const std::string &pattern){
size_t textSize = text.size();
size_t patternSize = pattern.size();
/*if(patternSize > textSize)
return -1;*/
vector<int> kmpNext = computeKmpPrefix(pattern);
int tIdx = 0;
int pIdx = 0;
vector<int> solutions;
while(tIdx < textSize){
if(pattern[pIdx] == text[tIdx]){
if(pIdx == patternSize - 1)
{
//return tIdx - (patternSize - 1); //index where the last comparison was ok
solutions.push_back( tIdx - (patternSize - 1) );
tIdx = tIdx - (patternSize - 2) ;
pIdx = 0;
}
tIdx++;
pIdx++;
}
else if(pIdx > 0){
pIdx = kmpNext[pIdx - 1];
}
else{
tIdx++;
}
}
//return -1;
return solutions;
}
int main()
{
ifstream f("strmatch.in");
ofstream g("strmatch.out");
string needle;
string haystack;
f >> needle >> haystack;
f.close();
vector<int> solutions =PatternMatcher::kmpSearch(haystack, needle);
g << solutions.size() << "\n";
for( int i = 0; i < solutions.size() && i < 1000; i++ )
g << solutions[i] << " ";
g << "\n";
return 0;
}