java实现算法之KMP匹配算法(三个关键点掌握即可理解)

来源:互联网 发布:质量好国产女装知乎 编辑:程序博客网 时间:2024/05/20 07:32

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具体实现代码

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;}elsereturn -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];}}}}
谢谢观看!

0 0
原创粉丝点击