KMP算法的Java实现(基于阮一峰的博客)

这个算法也看了大半天了,仔细看过两个人的博客,一个是传说中的Matrix67,另一个是阮一峰,个人感觉阮一峰的非常好理解,但是和百度其他人的做法有些出入,不过仍然是首选。Matrix67大神的也还可以,就是P[]的解释太复杂了,一整段文字带符号看得人欲仙欲死。
下面是两人的链接:
http://kb.cnblogs.com/page/176818/
http://www.matrix67.com/blog/archives/115

进入正题,这个算法不好理解的地方只有一个,就是预处理的next[]。看过阮一峰的博客之后,我感觉可以把next[]中存放的东西叫做循环的跳跃量,就是对长字符串的遍历不再以i++作为条件,而是以i+=next[j]作为条件。 这只是一种好理解的方法,真实意义还是要靠原博客去理解,而且这样写出来的预处理方法我总感觉不是O(m)的,还需要继续学习。

看了这么久,感觉头脑都不清醒了,有什么问题或细节上的错误欢迎指正。
import java.util.ArrayList;
import java.util.List;

public class General {

    public static void KMP(String a,String b){
        List<Integer> next = next_k(b);
        for(int i=0;i<a.length();){
            String result="";
            for(int j=0;j<b.length();j++){
                if(a.charAt(i+j)!=b.charAt(j)&&j!=0){
                    if(j==0){
                        i++;
                        break;
                    }
                    int offlen=j-next.get(j-1);
                    i+=offlen;
                    break;
                } else result+=b.charAt(j);
            }
            if(result.length()==b.length()){
                System.out.println(result+" "+i);
                break;
            }
        }
    }

    public static List<Integer> next_k(String b){
        List<Integer> next = new ArrayList<Integer>();
        for(int i=0;i<b.length();i++){
            next.add(i, 0);
        }
        int k=2;
        while(k<b.length()){
            for(int j=k;j>0;j--){
                if(b.substring(0,j).equals(b.substring(k-j+1, k+1))){
                    next.set(k, b.substring(0,j).length());
                    break;
                }
            }
            k++;
        }
        return next;
    }
    public static void main(String[] args) {
        String s = "asdfwqwqgweafasdf";
        String t = "dfw";
        KMP(s,t);
    }
}
两小时后改动。。。我认怂,标准的算法巧妙的多,但是原理也是一样,就是控制短字符串指针的偏移量。当然这种算出的next[]就是带-1的那种方法,需要去随便百度一个博客看一下生成规则。代码如下:
这里写代码片
static int KMP2( char[]  str, char[] ptr )
{
    int[] next = next(ptr);
    int s_i = 0, p_i = 0;

    while( s_i < str.length && p_i < ptr.length )
    {
        if( str[ s_i ] == ptr[ p_i ] ){
            s_i++;
            p_i++;
        }else{
            if( p_i == 0 ){
                s_i++;
            }
            else{
                p_i = next[ p_i - 1 ] + 1;
            }
        }
    }
    return ( p_i == ptr.length ) ? ( s_i - ptr.length ) : -1;
}
public static int[] next(char[] str){
    int[] next=new int[str.length];
    int i=0,j=1;
    next[0] = -1;
    for( i = 1; i < str.length; i++ )
    {
        j = next[ i - 1 ];
        while( str[ j + 1 ] != str[ i ] && ( j >= 0 ) )
        {
            j = next[ j ];
        }
        if( str[ i ] == str[ j + 1 ] )
        {
            next[ i ] = j + 1;
        }
        else
        {
            next[ i ] = -1;
        }
    }
    return next;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/u010698087/article/details/53507450
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞