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

来源:互联网 发布:linux ln s 什么意思 编辑:程序博客网 时间:2024/06/18 07:48
这个算法也看了大半天了,仔细看过两个人的博客,一个是传说中的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;}
0 0
原创粉丝点击