#include <iostream> #include <vector> #include <algorithm> #include <set> #include <string> #include <cstring> namespace patternMatch{ using namespace std; class boyerMoore{ public: boyerMoore(void):skip(NULL), shift(NULL), charMax(256){} int bmMake(const string &patternStr){ if( shiftMake(patternStr) < 0 || skipMake(patternStr) < 0) return -1; pattern = patternStr; } ~boyerMoore(void){ bmDesory(); } const int match(const string &target) const{ if(pattern.empty() || !shift || !skip || target.size() > pattern.size()) return -1; int targetLen = target.size(); int patternLen = pattern.size(); int i; int j = 0; while( j <= targetLen - patternLen){ for(i = patternLen -1; i >= 0 && target[i + j] == pattern[i]; i--); if(i < 0 ) return j; else j = max(shift[i], skip[pattern[i]] - (patternLen - 1 - i)); } } virtual void bmDebug(){ cout << "pattern string :" << pattern << endl; cout << "skip vec :" << endl; skipDebug(); cout << "shift vec:" << endl; shiftDebug(); } private: int skipMake(const string &patternStr); /**build assit vec used like kmp*/ void suffixMake(const string &pattern, int *suffix); int shiftMake(const string &patternStr); void skipDestory(void) { if(skip) delete skip; } void shiftDestory(void) { if(shift) delete shift; } void bmDesory(void){ skipDestory(); shiftDestory(); pattern.clear(); } virtual void skipDebug(void){ if(skip){ for(int pos = 0; pos < pattern.size(); pos++) cout << skip[pattern[pos]] << " "; cout << endl; } } virtual void shiftDebug(void){ if(shift){ for(int pos = 0; pos < pattern.size(); pos++) cout << shift[pos] << " "; cout << endl; } } int *skip; int *shift; string pattern; const int charMax; }; int boyerMoore::skipMake(const string &patternStr){ int pos; int patternLen = patternStr.size(); skipDestory(); if( NULL == (skip = new int[charMax])) return -1; else memset(skip, 0, charMax); for(pos = 0; pos < charMax; pos++) skip[pos] = patternLen; for(pos = 0; pos <= patternLen - 1; pos++) skip[(unsigned char)patternStr[pos]] = patternLen - pos - 1; return 0; } void boyerMoore::suffixMake(const string &pattern, int *suffix) { int patterLen = pattern.size(); suffix[patterLen - 1] = patterLen; for(int posMatch = patterLen - 2; posMatch >= 0; posMatch--){ int posCheck = posMatch; while(posCheck >= 0 && pattern[posCheck] == pattern[patterLen - 1 - (posMatch - posCheck)]){ posCheck--; } suffix[posMatch] = posMatch - posCheck; //cout << posMatch << "-suffix->" << suffix[posMatch] << endl; } } int boyerMoore::shiftMake(const string &patternStr){ int pos; int patternLen = patternStr.size(); shiftDestory(); if( NULL == (shift = new int[patternLen])) return -1; else memset(shift, 0, sizeof(int) * patternLen); int *suffix = new int[patternLen]; if(!suffix) return -1; else memset(suffix, 0, sizeof(int) * patternLen); /** make suffix for shift*/ suffixMake(patternStr, suffix); for(int pos = 0; pos < patternLen; pos++) shift[pos] = patternLen; int posMark = 0; for(int pos = patternLen - 1; pos >= 0; pos--){ if(suffix[pos] == pos + 1){ int posVal = patternLen - pos - 1; for(; posMark < posVal; posMark++) if( patternLen == shift[posMark]){ shift[posMark] = posVal; //cout << posMark << "->" << shift[posMark] << endl; } } } for(int pos = 0; pos < patternLen -1; pos++) shift[patternLen - suffix[pos] - 1] = patternLen - pos -1; if(suffix) delete suffix; return 0; } } using namespace std; using namespace patternMatch; int main() { string pattern, target; class boyerMoore bm; cout << "intput pattern match string" << endl; cin >> pattern; if(bm.bmMake(pattern) < 0){ cout << "Init pattern string fail" << endl; return -1; } bm.bmDebug(); cout << "intput target string" << endl; return 0; }
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithmios
http://wenku.baidu.com/link?url=-GK6uL1f_nvlHtZ3KNXfY_9ydgOTijIXoIapJBweNISBW_pZIvKKS6sshbpELw99VumsxKgxXYur8qRSHxvuN7ub5OiSXY9yPAOEm63NMju###
ssh