KMP算法中next函数的java实现
2014-07-24 17:20
337 查看
KMP算法中next函数的java实现
前言
今天看了July博主关于KMP算法的文章/article/1362918.html,写的很是深入浅出、浅显易懂,对于我这样的对KMP算法一知半解的小白来说获益匪浅。在此表示感谢,辛苦了!
下面是我看了 王红梅老师《算法设计与分析》的中关于next函数实现的一点小小感想,在此与大家分享,算是拿来主义吧^_^····
建议大家先将July博主的那边关于KMP算法仔细看下,启发还是很大的,虽然有了比KMP更高效的sunday 算法。
July文章中是先求出了“最大长度表”,然后通过向右“平移”首位补-1的方式求出,这种方式确实很直观很容易理解。
正文
我尽量说的浅显点,博主的语言表达能力欠佳啊·····┭┮﹏┭┮
还是先把程序贴出来吧,用java实现的,其实也就是将书中c++的描述,转换语言了一下而已。
测试用的模式串是:abcdabd,结果如下
下面我们讲讲next函数的原理,基是本将自己的理解表述出来,如有不当之处,还望指出
关于前、后缀可以理解为模式中的子串,只是位置不一样而已。
首先,设T是要求出next数组的模式串。假设,我们已经求出了next[0]、next[1]...next[j]的值(ps:next[j]是对应于T[j]的),那么如何求出next[j+1]的呢?
这时候我们可以设k = next[j],(公式不好编辑啊····)
子串S1 :T[0]...T[k-1]
子串S2 :T[j-k]...T[j-1]
则S1 = S2,互为真前后缀。这时候就要比较T[k] 和T[j]。
(一)、若T[k]=T[j],则next[j+1]=k+1.
(二)、若T[k]≠T[j],此时就要找到 T[0]...T[j-1]的真前、缀和真后缀相等的第二大子串,比如模式abcdabcbc, 比如T[0]T[1]T[2]=abc 与T[4]T[5]T[6]=abc是当前相等最大的前、后缀,此时要求出next[6]的值,这时候就要比较TT[3]和T[6],T[3]≠T[6],这时候就要退回到T[0]T[1]T[2]中求出最大的前、后缀是T[0]T[1]= T[4]T[5]=ab。从而next[k]的值为T[0]...T[k-1]的真前、后缀的相等的最大子串的长度,则T[0]...T[next[k]-1]即为T[0]...T[j-1]的真前、后缀相等的第二大子串。
令k=next[k],再比较T[k]和T[j],此时仍会出现两种情况:T[k]=T[j]和T[k]≠T[j]。
若T[k]=T[j]则按照(一)的方式处理;反之,则与(二)类似,在找出T[0]...T[j-1]的真前、后缀的相等的最大子串,重复(二)的过程,直到T[k]=T[j]或者next[k]=-1,如果T[0]...T[j-1]不存在真前、后缀相等的子串,此时next[j+1]=0.
这是代码:
其实原理不是特别难,只是书中的描述大都过于理论了,所以我们才会觉得无从下手,如果耐下性子仔细琢磨琢磨你会发下其实也没那么高深。
ps:有空我会把公式和原理图添加上的
前言
今天看了July博主关于KMP算法的文章/article/1362918.html,写的很是深入浅出、浅显易懂,对于我这样的对KMP算法一知半解的小白来说获益匪浅。在此表示感谢,辛苦了!
下面是我看了 王红梅老师《算法设计与分析》的中关于next函数实现的一点小小感想,在此与大家分享,算是拿来主义吧^_^····
建议大家先将July博主的那边关于KMP算法仔细看下,启发还是很大的,虽然有了比KMP更高效的sunday 算法。
July文章中是先求出了“最大长度表”,然后通过向右“平移”首位补-1的方式求出,这种方式确实很直观很容易理解。
正文
我尽量说的浅显点,博主的语言表达能力欠佳啊·····┭┮﹏┭┮
还是先把程序贴出来吧,用java实现的,其实也就是将书中c++的描述,转换语言了一下而已。
测试用的模式串是:abcdabd,结果如下
下面我们讲讲next函数的原理,基是本将自己的理解表述出来,如有不当之处,还望指出
关于前、后缀可以理解为模式中的子串,只是位置不一样而已。
首先,设T是要求出next数组的模式串。假设,我们已经求出了next[0]、next[1]...next[j]的值(ps:next[j]是对应于T[j]的),那么如何求出next[j+1]的呢?
这时候我们可以设k = next[j],(公式不好编辑啊····)
子串S1 :T[0]...T[k-1]
子串S2 :T[j-k]...T[j-1]
则S1 = S2,互为真前后缀。这时候就要比较T[k] 和T[j]。
(一)、若T[k]=T[j],则next[j+1]=k+1.
(二)、若T[k]≠T[j],此时就要找到 T[0]...T[j-1]的真前、缀和真后缀相等的第二大子串,比如模式abcdabcbc, 比如T[0]T[1]T[2]=abc 与T[4]T[5]T[6]=abc是当前相等最大的前、后缀,此时要求出next[6]的值,这时候就要比较TT[3]和T[6],T[3]≠T[6],这时候就要退回到T[0]T[1]T[2]中求出最大的前、后缀是T[0]T[1]= T[4]T[5]=ab。从而next[k]的值为T[0]...T[k-1]的真前、后缀的相等的最大子串的长度,则T[0]...T[next[k]-1]即为T[0]...T[j-1]的真前、后缀相等的第二大子串。
令k=next[k],再比较T[k]和T[j],此时仍会出现两种情况:T[k]=T[j]和T[k]≠T[j]。
若T[k]=T[j]则按照(一)的方式处理;反之,则与(二)类似,在找出T[0]...T[j-1]的真前、后缀的相等的最大子串,重复(二)的过程,直到T[k]=T[j]或者next[k]=-1,如果T[0]...T[j-1]不存在真前、后缀相等的子串,此时next[j+1]=0.
这是代码:
package Array; public class KMP_next { public static void Next(String str, int[] next) { int j = 0,k =-1; int len = str.length(); next[0] = -1; while(j < len-1){ //这个地方要注意是len-1 不是len,不然会数组越界的 if(k == -1){ next[++j] = 0; k = 0; } else if(str.charAt(j) == str.charAt(k)) { // 确定next(j+1)的值 k++; next[++j] = k; } else { k = next[k]; } } for(int i=0; i<next.length; i++) { System.out.printf(next[i] + " "); } } public static void main(String[] args) { // TODO Auto-generated method stub //String str = "abcdabd"; String str = "abcabcbc"; int[] next = new int[str.length()]; Next(str, next); } }
其实原理不是特别难,只是书中的描述大都过于理论了,所以我们才会觉得无从下手,如果耐下性子仔细琢磨琢磨你会发下其实也没那么高深。
ps:有空我会把公式和原理图添加上的
相关文章推荐
- java实现kmp算法
- 字符串匹配之KMP算法思路、原理与Java实现
- KMP算法及Java实现
- KMP算法的实现(Java语言描述)
- KMP算法的实现(Java语言描述)
- KMP算法Java实现
- hdu 2594 java实现字符串KMP算法
- KMP算法java实现
- KMP算法java实现
- 对KMP的理解,以及kmp算法java版本实现
- 字符匹配KMP算法 java实现
- 【算法总结】KMP算法及java实现
- Java实现KMP算法
- Java实现KMP算法(转)
- KMP算法----java实现
- Java实现KMP算法
- 字符串搜索的KMP算法实现(java版)
- KMP算法中next函数的实现
- KMP算法Java实现
- 数据结构Java实现——③串--->串的模式匹配:Brute-Force算法和 KMP算法