Created
January 10, 2013 06:10
-
-
Save ws6/4499826 to your computer and use it in GitHub Desktop.
a fabulous KMP tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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