数据结构——关于KMP算法中next函数的详细解析
来源:互联网 发布:2017网络春晚直播 编辑:程序博客网 时间:2024/05/17 22:31
之前看到数据结构中字符串的模式匹配时,花了半天的时间,才把KMP算法中的next函数整明白了,结果过了几天在看到这时,只记得next[j+1]=next[j]+1,可是有时候能套公式正确算出,有时候就算不对,所以今天再重新理一遍思路,顺便记录下来,防止哪天脑子再短路了,又不知道怎么求解的了。
先看看next数据值的求解方法位序 1 2 3 4 5 6 7 8 9
模式串 a b a a b c a b c
next值 0 1 1 2 2 3 1 2 3
next数组的求解方法是:
1.第一位的next值为0
2.第二位的next值为1
后面求解每一位的next值时,根据前一位进行比较
3.第三位的next值:第二位的模式串为b ,对应的next值为1;将第二位的模式串b与第一位的模式串a进行比较,不相等;则第三位的next值为1(其他情况均为1)
4.第四位的next值:第三位的模式串为a ,对应的next值为1;将第三位的模式串a与第一位的模式串a进行比较,相同,则第四位的next值得为1+1=2
5.第五位的next值:第四位的模式串为a,对应的next值为2;将第四位的模式串a与第二位的模式串b进行比较,不相等;第二位的b对应的next值为1,则将第四位的模式串a与第一位的模式串a进行比较,相同,则第五位的next的值为1+1=2
6.第六位的next值:第五位的模式串为b,对应的next值为2;将第五位的模式串b与第二位的模式中b进行比较,相同,则第六位的next值为2+1=3
7.第七位的next值:第六位的模式串为c,对应的next值为3;将第六位的模式串c与第三位的模式串a进行比较,不相等;第三位的a对应的next值为1,
则将第六位的模式串c与第一位的模式串a进行比较,不相同,则第七位的next值为1(其他情况)
8.第八位的next值:第七位的模式串为a,对应的next值为1;将第七位的模式串a与第一位的模式串a进行比较,相同,则第八位的next值为1+1=2
9.第八位的next值:第八位的模式串为b,对应的next值为2;将第八位的模式串b与第二位的模式串b进行比较,相同,则第九位的next值为2+1=3
如果位数更多,依次类推
KMP算法的关键在于求算next[]数组的值,即求算模式串每个位置处的最长后缀与前缀相同的长度,下面按照递推的思想总结一下求解next[]数组:
根据定义next[1]=0,假设next[j]=k, 即P[1...k-1]==P[j-k,j-1]
1)若P[j]==P[k],则有P[1..k]==P[j-k,j],很显然,如果next[j]=k; 则next[j+1]=next[j]+1=k+1;否则next[j+1]=k+1!=next[j]+1;(当初就想着记公式简单可以直接套用呢,结果只记住next[j+1]=next[j]+1以至于后来迷糊了)2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。
因此可以这样去实现:
void getNext(char *p,int *next){ int j,k; next[1]=0; j=1; k=0; while(j<strlen(p)-1) { if(k==0||p[j]==p[k]) //匹配的情况下,p[j]==p[k],next[j+1]=k+1; { j++; k++; next[j]=k; } else //p[j]!=p[k],k=next[k] k=next[k]; }}
KMP模式匹配算法改进:
后来有人发现其实KMP算法还是有缺陷的,比如主串S=“aaaabcde”,子串T=“aaaaag”,其next数组为012345;当i=5 ,j=5是“b”与“a”不匹配,此时j=next[5]=4,又发现j=4时,“b”与“a”不匹配,依次类推,直到j=next[1]=0;此时i++,j++,i=6,j=1从而我们发现中间有多余的判断,由于子串T中第2、3、4、5位置的字符都与首位的“a”相同,即可以用首位next[1]的值去取代与它字符相等的后续next[j]的值,即next数组改为000005,此时由i=5,j=5时“b”与“a”不匹配,此时j=next[5]=0;此时i++,j++得到i=6,j=1,即可省去中间的多余判断。因此我们需要改进next函数的求解方法。
/* 求模式串T的next函数修正值并存入数组nextval */void get_nextval(String T, int *nextval) { int i,j; i=1; j=0; nextval[1]=0; while (i<T[0]) /* 此处T[0]表示串T的长度 */ { if(j==0 || T[i]== T[j]) /* T[i]表示后缀的单个字符,T[j]表示前缀的单个字符 */{ ++i; ++j; if (T[i]!=T[j]) /* 若当前字符与前缀字符不同 */ nextval[i] = j;/* 则当前的j为nextval在i位置的值 */ else nextval[i] = nextval[j];/* 如果与前缀字符相同,则将前缀字符的 *//* nextval值赋值给nextval在i位置的值 */ } else j= nextval[j];/* 若字符不相同,则j值回溯 */ }}
3 0
- 数据结构——关于KMP算法中next函数的详细解析
- 关于KMP算法中next函数的详细解析
- KMP算法中next函数的解析
- KMP算法中next函数的解析
- 关于KMP算法当中的next函数
- 关于KMP算法当中的next函数
- KMP算法中next函数的实现
- KMP算法中next函数
- 经典算法之KMP中next函数解析
- 数据结构KMP算法中next函数的求解思想及其解释
- 关于KMP算法中前缀函数(next函数)的一点个人理解
- KMP算法 next函数 代码解析
- 关于KMP算法中next函数值的求法(举例说明,看不懂你砍我)
- 个人学习——数据结构:KMP算法next函数序列计算
- <转>KMP算法中关于next数组的探究
- KMP算法中关于next数组的探究
- KMP算法中关于next数组的探究
- KMP算法中next函数的java实现
- 名人名言
- Dll的显式和隐式调用
- VS2010+opencv2.4.10调试显示Cannot find or open the PDB file出不了图片问题。
- KVC,KVO
- 单工?半双工?全双工?
- 数据结构——关于KMP算法中next函数的详细解析
- C++ Primer 第4版中的Sales_item.h源码
- 安装grid时运行root.sh报错的解决方法
- 拓扑排序 HDU 1285 确定比赛名次
- Java多线程调度方法
- 彻底弄懂css中单位px和em,rem的区别
- Github上传代码菜鸟超详细教程【转】
- 求输入数的平均数
- 一个弹出层的效果插件 layer