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);
}
}