参考http://blog.csdn.net/v_july_v/article/details/7041827
#include "StringMatching.h" StringMatching::StringMatching(void) { } StringMatching::~StringMatching(void) { } /*返回子串T在主串S中第pos个字符串之后的位置。若不存在,则返回0*/ int StringMatching::SimpleStringMatch(char* S,char* T,int pos) { int sLen = strlen(S); int tLen = strlen(T); int i = pos; //i用于主串S中当前位置下标。若pos不为1,则从pos位置开始匹配 int j = 0 ; //j用于子串T中当前位置下标值 while(i < sLen && j < tLen) { if (S[i] == T[j]) { i++; j++; } else { i = i-j+1;//i退回到上次匹配首位的下一位 j = 0; } } if (j == tLen) return i - j; else return -1; } //KMP模式匹配算法 /*通过计算返回子串T的next数组*/ void StringMatching::get_next(char* T,int *next) { int tLen = strlen(T); int j,k; j = 0; k = -1; next[0] = -1; while (j < tLen) { if (k == -1 || T[j] == T[k]) { j++; k++; next[j] = k; } else { k = next[k] ;//若字符不相同,则j值回溯 } } } //改良后的KMP算法,只改进next数组的推导 /*通过计算返回子串T的next数组*/ void StringMatching::get_nextval(char* T,int *nextval) { int tLen = strlen(T); int j,k; j = 0; k = -1; nextval[0] = -1; while (j < tLen) //此处T[0]表示串T的长度 { if (k == -1 || T[j] == T[k]) { j++; k++; if (T[j] != T[k]) nextval[j] = k; else nextval[j] = nextval[k]; //如果与前缀字节相同,则将前缀字节的nextval值赋给i位置的值 } else { k = nextval[k] ;//若字符不相同,则j值回溯 } } } //flag不为0是改善后的KMP int StringMatching::KMP(char* S,int pos,int flag) { int sLen = strlen(S); int tLen = strlen(T); int i = pos ; int j = 0; int next[255]; if (flag == 0) { get_next(T,next); } else { get_nextval(T,next); } while (i < sLen && j < tLen) { if (j == -1 || S[i] == T[j]) { i++; j++; } else { j = next[j]; //j退回合适的位置,i不变 } } if (j == tLen) return i - j; else return 0; }
void TEST_StringMatch() { char* p = "I am very unhappy!"; char* T = "happy"; StringMatching st; int resultSimpleStringMatch = st.SimpleStringMatch(p,T,0); int resultKMP = st.KMP(p,0); int resultKMP_2 = st.KMP(p,1); }