KMP算法模板
原理
见参考文章
模板
#include <iostream> #include <cstring> #define max_n 100005 using namespace std; char s[max_n] = {'a','a','b','a','a','a','b','c'}; char p[max_n] = {'a','a','a','b'}; int nxt[max_n];//nxt跳转表,nxt[k]表示在k之前有的最大相同前后缀的长度 void get_next(char* p,int nxt[])//构造nxt表 { int pLen=strlen(p); nxt[0] = -1;//nxt表首元素必为-1,表示没元素会和他配对,要重新开始匹配模式串 int k = -1;//初始为-1,重新开始的标志也是-1 int j = 0; while(j<pLen-1) { //p[j]是后缀,p[k]是前缀 if(k=-1||p[j]==p[k])//如果重新匹配或者成功匹配 { ++j; ++k; if(p[j]!=p[k]) { nxt[j] = k; } else nxt[j] = nxt[k];//避免p[j]==p[nxt[j]],所以继续递归,k=nxt[k]=nxt[nxt[k]] } else { k = nxt[k]; } } } int KMP(char* s,char* p) { int i = 0;//原串 int j = 0;//模式串 int sLen = strlen(s); int pLen = strlen(p); while(i<sLen&&j<pLen) { if(j==-1||s[i]==p[j])//若匹配或者j==-1 { ++i; ++j; } else//若失配且j!=-1 { j = nxt[j]; } } if(j==pLen) { return i-j;//返回成功匹配的第一个开始位置,此时j=pLen } else { return -1;//未找到匹配字串 } } int main() { get_next(p,nxt); for(int i = 0;i<4;i++) { cout << nxt[i] << " "; } cout << endl; cout << KMP(s,p) << endl; return 0; }
参考文章
v_JULY_v,从头到尾彻底理解KMP(2014年8月22日版),https://blog.csdn.net/v_july_v/article/details/7041827 (一篇通透)