我们采用的教材是严蔚敏老师的数据结构教材。无论是旧版还是新版,关于kmp的部分是相同的。
课本关于kmp的说明还算详细,仔细阅读不难看懂。
问题在于,在实现get_next算法时,所使用的符号和描述方法根理论部分不一样!!!
就好比你介绍的是用普通锅蒸米饭,举例的时候却用了电饭煲。
下面我就不多言了,把我的get_next函数和get_nextval函数的代码贴过来。
由于本人水平有限,如果发现错误,请留言哦。
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//求next函数
void get_next2(string p,vector<int> &next);
//求next函数的修正值
void get_nextval(string p,vector<int> next,vector<int> &nextval) ;int main(void)
{//string p="$ababaaababaa";//string p="$aaaabaaaab";string p="$abaabcac";cout<<"模式串为:" <<endl;for(int i=1;i<=p.size()-1;i++)cout<<p[i]<<" ";cout<<endl;//下面计算next函数 vector<int> next;next.resize(p.size());get_next2(p,next);//下面输出对应next函数值 for(int i=1;i<=next.size()-1;i++)cout<<next[i]<<" ";cout<<endl;//下面计算next函数修正值 vector<int> nextval; get_nextval(p,next,nextval);for(int i=1;i<=nextval.size()-1;i++)cout<<nextval[i]<<" ";cout<<endl;return 0;
}void get_next2(string s,vector<int> &next)
{next[1]=0;next[2]=1;int k,j;j=2;while(1){if(j>=next.size()-1)//到达倒数第二个字符,退出循环break;k=next[j];while(k!=0){if(s[j]==s[k])break;else{k=next[k];//回溯}}next[j+1]=k+1;j++;}
}void get_nextval(string p,vector<int> next,vector<int> &nextval)
{//在已有next的基础上,取修正值;
//不像课本上那样混为一谈。 nextval=next;//赋值 int j,k;for(j=2;j<nextval.size();j++){ k=nextval[j]; while(p[j]==p[k]){ k =nextval[k];nextval[j] =k;} }}