部分文章内容为公开资料查询整理,原文出处可能未标注,如有侵权,请联系我,谢谢。邮箱地址:gnivor@163.com ►►►需要气球么?请点击我吧!

Java算法--字符串检索 KMP算法

彻底理解KMP:http://blog.csdn.net/v_july_v/article/details/7041827

KMP算法:http://blog.csdn.net/yutianzuijin/article/details/11954939

KMP求next和nextval:http://blog.sina.com.cn/s/blog_59b4a0b701015jtk.html

KMP算法讲解:http://www.cnblogs.com/c-cloud/p/3224788.html

KMP算法理解实现:http://kenby.iteye.com/blog/1025599

严蔚敏KMP:http://wenku.baidu.com/view/3ecafcd3a58da0116c1749eb.html

 

 

严版:

获取next数组:

//获取next数组
public static int[] GetNext(String str){
    int j ,k;
    int next[] = new int[str.length()];
    j=0;k=-1;next[0]=-1;
    while(j<str.length()-1){
        if(k==-1||str.charAt(j)==str.charAt(k)){
            j++;k++;
            next[j]=k;
        }
        else k=next[k];
    }        
    return next;        
}

改进:获取nextval数组

//获取nextval数组
public static int[] GetNextval(String str){
    int j ,k;
    int nextval[] = new int[str.length()];
    j=0;k=-1;nextval[0]=-1;
    while(j<str.length()-1){
        if(k==-1||str.charAt(j)==str.charAt(k)){
            j++;k++;
            if(str.charAt(j)!=str.charAt(k)){
                nextval[j]=k;
            }
            else nextval[j]=nextval[k];
        }
        else k=nextval[k];
    }        
    return nextval;        
}

搜索子串:

//搜索子串
public static int search(String mystr,String find){
    int next[] = GetNext(find);
    int i = 0,j=0,v;
    while(i<mystr.length()&&j<find.length()){
        if(j==-1||mystr.charAt(i)==find.charAt(j)){
            i++;j++;
        }
        else j=next[j];
    }
    if(j>=find.length())
        v=i-find.length();
    else 
        v=-1;
    return v;
}

main函数:

public static void main(String args[]){
    String str1 ="ababbacbababcbce";
    String find="ababc";
int[] next = GetNext(find);    
    for(int i = 0 ; i <next.length ; i++){
        System.out.print(next[i]+" ");
    }
    System.out.println("开始搜索...");
    int i = search(str1,find);
    System.out.println(i);
}

严版的next数组和nextval数组:

字符串 a b a b b a c b a b a b c b c e
next -1 0 0 1 2 0 1 0 0 1 2 3 4 0 0 0
nextval -1 0 -1 0 2 -1 1 0 -1 0 -1 0 4 0 0 0

例如用abacb...和上面的字符串比较

如果是next数组比较到c!=b,那么,c还要和第一个b进行比较

如果是nextval数组,因为之前生成的时候已经考虑了str.charAt(1)==str.charAt(3),所以c不用再和第一个b进行比较,直接和最开始的a比较即可。

=================

另一个版本:

public class MyKmp {
    public static void main(String args[]){
        String str1 ="ababcbacbababcbce";
        String find="ababc";
        int[] next = getNext(find);
        for(int i = 0 ; i <next.length ; i++){
            System.out.print(next[i]+" ");
        }
        System.out.println();
        search(str1,find,next);
    }

    //获取next数组
    public static int[] getNext(String str){
        int len = str.length();
        int j = 0;
        int next[] = new int[len];
        next[0]=next[1]=0;
        for(int i = 1 ;i<len-1 ; i++){
            while(j>0&&str.charAt(i)!=str.charAt(j))
                j=next[j];
            if(str .charAt(i)==str.charAt(j)){
                j++;
            
            }
            next[i+1]=j;
            
        }
        return next;
    }
    
    //搜索子串
    public static void search(String original,String find, int next[]){
        int j = 0;
        for(int i = 0 ; i < original.length() ;i ++){
            while(j>0 && original.charAt(i)!=find.charAt(j))
                j=next[j];
            if(original.charAt(i)==find.charAt(j)){
                if(j==find.length()-1){
                    System.out.println("找到字符串,位置在"+(i-j));
                    System.out.println(original.subSequence(i - j , i + 1));
                    System.out.println(j);
                    //return;
                    j=next[j];
                }
                else
                    j++;
            }
        }        
    }
}

 

posted @ 2015-05-05 21:22  流了个火  阅读(776)  评论(0)    收藏  举报
►►►需要气球么?请点击我吧!►►►
View My Stats