Skip to content

Instantly share code, notes, and snippets.

@ws6
Created January 10, 2013 06:10
Show Gist options
  • Save ws6/4499826 to your computer and use it in GitHub Desktop.
Save ws6/4499826 to your computer and use it in GitHub Desktop.
a fabulous KMP tutorial
//http://dev-faqs.blogspot.com/2010/05/knuth-morris-pratt-algorithm.html
#include "PatternMatcher.h"
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;
}
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;
while(tIdx < textSize){
if(pattern[pIdx] == text[tIdx]){
if(pIdx == patternSize - 1)
return tIdx - (patternSize - 1);
tIdx++;
pIdx++;
}
else if(pIdx > 0){
pIdx = kmpNext[pIdx - 1];
}
else{
tIdx++;
}
}
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment