KMP算法实现
2017-09-08 17:20
274 查看
import java.util.Scanner; //KMP算法, T(n)=O(N+M) public class Main{ public static void main(String []args){ Scanner sc=new Scanner(System.in); String s=sc.nextLine(); String t=sc.nextLine(); System.out.println(KMPIndex(s, t)); } public static int[] getNext(String t){ if(t.length()==1){ return new int[]{-1}; } int next[]=new int[t.length()]; next[0]=-1;//初始为-1 next[1]=0;//初始为0 int pos=2;//指向next的当前位置 int cn=0;//记录当前位置最大前后缀数目 while(pos<t.length()){ if(t.charAt(pos-1)==t.charAt(cn)){//i-1位置字符等于前缀的后一个字符,next[i]=next[i-1]+1 next[pos++]=++cn; }else if (cn>0) { cn=next[cn];//cn>0,依次从左找最长匹配前缀。 }else { next[pos++]=0; } } return next; } public static int KMPIndex(String s,String t){//返回第一个匹配的下标,若不匹配,返回-1 if(s.length()<t.length()){ return -1; } int next[]=getNext(t);//得到next数组 int i=0,j=0; while(i<s.length()&&j<t.length()){ if(j==-1||s.charAt(i)==t.charAt(j)){//j==-1是当第一个都不匹配的情况下,j也要++ i++; j++; }else { j=next[j];//相当于将t字符串右移动到后缀匹配最大的位置的下一个字符。从这个字符开始比较 } } if(j>=t.length()){//得到第一个开始匹配的下标 return (i-t.length()); }else { return -1; } } }