KMP是处理字符串匹配的常用算法之一,这个理解起来比较简单(其实我感觉还是挺费劲的,但是书上都这么说,我果然还是太菜~),还有别的算法像是后缀数组、AC自动机等等,以后有机会再写一下
基本思想我也是学习的Matrix67的博客 http://www.matrix67.com/blog/archives/115,我就简单把代码整理一下,加了一点我自己的注释
#include<iostream> #include<string.h> #include<algorithm> using namespace std; #define maxn 1000 string A; string B; int p[maxn]; //自匹配过程,找出满足B[1,p[j]]=B[j-p[j]+1,j]的最大p[j](就是前X个字符==后x个字符的最大x) void predeal() { int m=B.size(); p[0]=-1;//初始化p[0],也就是执行到p[0]说明该位置不存在自匹配了 int j=-1; for(int i=1;i<m;i++) { //如果当前字符不相等,就将j移动到上一个自匹配位置 while(j>-1&&B[j+1]!=B[i]) j=p[j]; //如果相等,自匹配位置+1即可 if(B[j+1]==B[i]) j++; //对自匹配数组赋值 p[i]=j; } } //主要匹配过程 void kmp() { bool flag=false; predeal(); int n=A.size(); int m=B.size(); int j=-1; for(int i=0;i<n;i++) { //如果当前位置不相等,将j移动到上一个B串自匹配位置,相当于将B向A的右侧移动,直到再次匹配 while(j>-1&&A[i]!=B[j+1]) j=p[j]; //如果相等,那么将j+1 if(A[i]==B[j+1]) j++; //如果j==m-1,说明找到啦,over?no!there may be more answers~ if(j==m-1) { cout<<"Pattern occurs at "<<i-m+1<<endl; flag=true; break;// solve problems that only have to answer yes or no //j=p[j]; continue to find more suitable patterns } } if(!flag) cout<<"cant find string b in string a"<<endl; } int main() { while(cin>>A>>B) { kmp(); return 0; } }