BF算法和KMP算法解析

查找字符串无非两种常用的,一是BF(宝宝算法)二是天阶算法KMP。

主串:ABCDABCE

模式串ABCE

问题:找出模式串在主串的位置

先说简单的BF算法:

BF是通过先比较,匹配的话就模式串指针和主串指针向前移动,不匹配的回溯。

代码:

public class T {

    public static int indexof(String target,String pattern,int beg)
    {
        int m=target.length();//主串
        int n=pattern.length();//子串,模式串
        int i=beg;//主串指针
        int j=0;//模式串指针
        if (m==0||mm)
        {
            return -1;
        }
        while (i

简单的BF算法就解决了

下面是KMP算法:

KMP不是一个一个向前移,而是前移模式串匹配的

例如:

                    i

target:   ababacaeabac

pattern: abac

                    j

发现i指针对应的与j只针对应的不一样:他所采取的是:

                    i

target:   ababacaeabac

pattern:     abac

                    j

直接移动到这儿,为什么呢?应为模式串存在这样的第一个和第三个同样是a,第三个a和主串的a是匹配的,那么第一个a必然也是匹配的。所以我们直接把第一个a移动到第三个a那个位置。后面的以此类推。

那么它是怎么精准的实现的呢?

那就得益于next[]数组了每次回退依靠next数组进行精准定位

abac它的next数组为:

-1,0,0,1

它是看当前模式串的指针前面的数据有多少个相同的就记录下来,下次会退的时候不会直接回溯,

                    i

target:   ababacaeabac

pattern: abac

                    j

此时不匹配,j=next[j];

j=1;

pattern: abac

                j

j就在这儿了,继续检索,匹配;

而不是回到第一个a那。

那么为什么会移动那儿,而不是其他位置呢?

原因是:next数组是专门处理模式串数组的,他记录有多少个重复元素,下次回退就回退重复元素后一个,继续比较,就不用BF那样繁琐的一个一个移动了。

拿上面那个pattern串来说:

匹配到了,c那个位置时,发现不匹配了,但是c前面有两个相同的元素a就可以直接把j指针移到第一a下面那个元素,就相当于下面这个操作,模式串往后移,使主串的第二个a与模式串第一个a匹配。

                    i

target:   ababacaeabac

pattern:    abac

                    j

代码如下:

public class kpm3 {
    private static int next[];//定义一个next数组
    public static int[] getNext(String pattern) {获取next数组

       int next[]=new int[pattern.length()];//开辟空间
        int j=0;
        int k=-1;
        next[0]=-1;//很重要,不能忘了
        while (jlength||length

东西有点多,还请耐心看完。

你可能感兴趣的:(算法,算法,java,开发语言)