天天看點

改進後的KMP算法的java實作

import java.util.Scanner;

/*
 * 改良後的KMP算法
 * 解決了普通kmp算法依然存在的一些問題
 */
public class BetterKmp {
	static int[] nextval=new int[100];                  //next數組   
    public static void  get_nextval(String a)           //用來求next數組
    {
      // 第一位設為-1,友善判斷目前位置是否為搜尋詞的最開始
        nextval[0] = -1;
        int i = 0;
        int j = -1;
        while(i < a.length()) {
            if (j == -1 || a.charAt(i) == a.charAt(j)) {
                i++;
                j++;
                if(i < a.length()&&a.charAt(i)!=a.charAt(j))
                	nextval[i]=j;
                else if(i < a.length()&&a.charAt(i)==a.charAt(j))
                	nextval[i]=nextval[j];
            } else {
                j = nextval[j];
            }
        }
    }
    public static int get_index(String a,String b)   //用于在主串中搜尋子串
    {
    	int a1=0;
    	get_nextval(b);
    	int i=0;
    	int j=0;
    	while(i<a.length()&&j<b.length())
    	{
    		if(j==0||a.charAt(i)==b.charAt(j))    //用來對比使用
    		{
    			if(a.charAt(i)!=b.charAt(j))
    			{
    				i++;
    				continue;
    			}
    			i++;
    			j++;
    		}
    		else
    		{
    			j=nextval[j];
    		}
    	}
    	if(j>=b.length())
    	{
    	  return i-b.length();
    	}
    	else
    	{
    		return -1;
    	}
    }
    public static void main(String[] args)
    {
    	Scanner in=new Scanner(System.in);
    	System.out.println("請輸入主字元串");
    	String a;
    	a=in.nextLine();
    	System.out.println("請輸入副字元串");
    	String b;
    	b=in.nextLine();    //獲得主副字元串
    	int mk=get_index(a,b);
    	for(int i=0;i<b.length();i++)
    		System.out.println(nextval[i]);
    	if(mk==-1)
    	{
    		System.out.println("主字元串中不包含子串");
    	}
    	else
    		System.out.println("子串在主串中的索引位置為"+mk);
    }
}
           

繼續閱讀