java实现算法之KMP匹配算法(三个关键点掌握即可理解)
2017-03-13 11:38
405 查看
KMP算法在网上已经有很多详细解释的博客,这里我就不多解释其匹配过程了,只对我在学习KMP算法时遇到的一些关键点和难理解的地方做出解释。我觉得只要能看懂我要解释的这几点,kmp算法一定可以轻松的理解。
最好是先了解了什么是kmp匹配算法,和next数组时干什么的之后,再来看这篇文章,有助于你更好的理解,和更容易编写出kmp匹配算法。
首先我们要知道kmp算法,最关键的地方也是最难的地方就是next数组的构造过程,只要能把next数组的构造过程理解清楚,kmp算法基本就没有任何的难点了,下面我就只讲解next数组构造过程中需要注意和难理解的地方。
第一个关键点,就是next数组的构造过程实际上就是模式串自身匹配的过程,通过与自身匹配找到其与主串匹配时最小需要回溯的位置,其与自身匹配的过程实际上也是利用next数组的匹配。
第二个关键点,就是模式串与自身匹配,开始时指针是要相错一位的,其中一个指针i指向模式串第一位,另一个指针j指向模式串第一位的前一位也就是-1位,(-1位默认和任何字符匹配)这样好理解。
i
a b a a b c a c
a b a a b c a c
j
条件有限,就是上面这种情况,可能现在你还没办法理解,等你看过关键点三,在回过头来看,可能会有更好的理解
第三个关键点,就是它是如何通过这种匹配过程来求出next数组的呢,下面我们在来看一种情况:
i
a b a a b c a c
a b a a b c a c
j
当出现上述情况时,我们发现i指针和j指针指向的字符匹配了,这时候我们想,当用这个模式串和别的主串匹配时,当在i指针指向的下一个字符即i+1与主串不匹配时,是不是只要我们将模式串回溯到j指针指向的下一个位置即j+1就好了,因为此时我们知道,i和j是匹配的,我们只需要判断i+1和j+1是否匹配就好,也就是下面i和j指针指向的情况:
i
主串: a b a c a b a a b c
模串: a b a a b c a c
j
回溯: a b a a b c a c
因此在求next数组时,当我们发现i指针和j指针匹配时,只需让i指针下一位的next数组等于j指针指向的下一位即可,也就是next[i+1]=j+1;
当i指针和j指针不匹配时,我们只需让j指针回溯至next[j]位置即可,然后利用next数组继续匹配即可构造出next数组。
下面是java具体实现代码
最好是先了解了什么是kmp匹配算法,和next数组时干什么的之后,再来看这篇文章,有助于你更好的理解,和更容易编写出kmp匹配算法。
首先我们要知道kmp算法,最关键的地方也是最难的地方就是next数组的构造过程,只要能把next数组的构造过程理解清楚,kmp算法基本就没有任何的难点了,下面我就只讲解next数组构造过程中需要注意和难理解的地方。
第一个关键点,就是next数组的构造过程实际上就是模式串自身匹配的过程,通过与自身匹配找到其与主串匹配时最小需要回溯的位置,其与自身匹配的过程实际上也是利用next数组的匹配。
第二个关键点,就是模式串与自身匹配,开始时指针是要相错一位的,其中一个指针i指向模式串第一位,另一个指针j指向模式串第一位的前一位也就是-1位,(-1位默认和任何字符匹配)这样好理解。
i
a b a a b c a c
a b a a b c a c
j
条件有限,就是上面这种情况,可能现在你还没办法理解,等你看过关键点三,在回过头来看,可能会有更好的理解
第三个关键点,就是它是如何通过这种匹配过程来求出next数组的呢,下面我们在来看一种情况:
i
a b a a b c a c
a b a a b c a c
j
当出现上述情况时,我们发现i指针和j指针指向的字符匹配了,这时候我们想,当用这个模式串和别的主串匹配时,当在i指针指向的下一个字符即i+1与主串不匹配时,是不是只要我们将模式串回溯到j指针指向的下一个位置即j+1就好了,因为此时我们知道,i和j是匹配的,我们只需要判断i+1和j+1是否匹配就好,也就是下面i和j指针指向的情况:
i
主串: a b a c a b a a b c
模串: a b a a b c a c
j
回溯: a b a a b c a c
因此在求next数组时,当我们发现i指针和j指针匹配时,只需让i指针下一位的next数组等于j指针指向的下一位即可,也就是next[i+1]=j+1;
当i指针和j指针不匹配时,我们只需让j指针回溯至next[j]位置即可,然后利用next数组继续匹配即可构造出next数组。
下面是java具体实现代码
package KMPMatch; import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in=new Scanner(System.in); String s1=in.nextLine(); String s2=in.nextLine(); in.close(); System.out.println(kmpMatch(s1,s2)); } public static int kmpMatch(String s1,String s2){ int []next=new int[s2.length()]; getNext(s2,next); int n1=s1.length(); int n2=s2.length(); int i=0,j=0; while(i<n1&&j<n2 ){ if(j==-1||s1.charAt(i)==s2.charAt(j)){ i++; j++; }else{ j=next[j]; //i=i-j+1;j=0;//简单的模式串匹配算法 } } if(j>=n2){//j>=n2实际上只能取到j=n2,表明模式串已经匹配完毕 return i-n2; }else return -1; } public static void getNext(String s,int []next){ int i=-1,j=0;//模式串与自身匹配时,相错一位 int n=s.length(); next[0]=-1; while(j<n-1){//j这里为n-1是因为求next数组时是求相等的后一位的next值. if(i==-1||s.charAt(i)==s.charAt(j)){//s.charAt在-1时报错,因此此时应添加条件跳过此情况 i++; j++;//先加加后匹配 next[j]=i; }else{ i=next[i]; } } } }谢谢观看!
相关文章推荐
- KMP模式匹配算法原理分析、next数组优化及java实现
- java实现字符串的一般和KMP模式匹配算法
- 理解与实现KMP模式匹配算法
- KMP字符串模式匹配算法Java实现
- KMP,父串匹配子串算法,java实现
- Java KMP匹配算法的实现
- Kmp字符匹配算法优化C++实现
- 数据结构之串的KMP模式匹配算法的实现
- KMP模式匹配算法的两点理解
- 数据结构Java实现——③串--->串的模式匹配:Brute-Force算法和 KMP算法
- KMP算法介绍及实现——轻松搞定KMP匹配算法
- 9.KMP模式匹配算法实现o(n)复杂度的匹配
- KMP快速模式匹配的java实现
- 模式匹配 -- KMP 算法原理与实现
- KMP模式匹配算法实现
- 使用栈实现括号匹配算法-java
- 经典算法研究:模式匹配(子串匹配)之 KMP 算法(C语言实现版)
- KMP模式匹配算法的一些理解
- 关于“泊松分酒”的算法理解,实现遍历所有情况(JAVA)
- 字符串算法--KMP--Java实现