这里直接给出的是优化后的NextVal的数组
(1)改进后的NextVal数组和改进前的Next数组的区别:当计算得出的Next[j]=k时,说明若pattern串中第j位与当前主串中的第i位不匹配时,模式串需要回到第k位继续跟主串中第i位继续比较,但是如果我们计算出的pattern[j]==pattern[k],那么再让pattern[k]与main[i]比较就没有意义,肯定不匹配,所以可在构造next数组时就进行判定,如果相等就直接赋值next[j]=next[k]
(2)KMP模式匹配充分利用了模式串前缀和后缀的特点,使得不需要主串回溯,但其实不好理解,唉。
package test;
import java.util.Scanner;
public class Main {
static int []next;
public static void main(String[] args) {
//KMP
Scanner in=new Scanner(System.in);
String mainString=in.next();
String patternString=in.next();
System.out.println(mainString);
System.out.println(patternString);
getNextVal(patternString);
int location=KMP(mainString,patternString);
if(location==-1){
System.out.println("模式不匹配");
}
else{
System.out.println("模式匹配成功,位置为:"+location);
}
}
public static void getNextVal(String patternString){
int m=patternString.length();
next=new int[m+1];
int i=0;
int k=-1;
next[0]=-1;
while(i<m-1){
if(k==-1||patternString.charAt(i)==patternString.charAt(k)){
++i;
++k;
if(patternString.charAt(i)==patternString.charAt(k)){
next[i]=next[k];
}
else{
next[i]=k;
}
}
else{
k=next[k];
}
}
for(int x:next){
System.out.print(x+"、");
}
System.out.println();
}
public static int KMP(String mainString,String patternString) {
int i=0;
int j=0;
while(i<mainString.length()&&j<patternString.length()){
if(j==-1||mainString.charAt(i)==patternString.charAt(j)){
j++;
i++;
}
else{
j=next[j];
}
}
if(j>=patternString.length()){
return i-patternString.length();
}
else{
return -1;
}
}
}