kmp算法java实现

一:暴力解法

KMP算法要解决的问题就是在字符串(也叫主串)中的模式(pattern)定位问题。说简单点就是我们平时常说的关键字搜索。模式串就是关键字(接下来称它为P),如果它在一个主串(接下来称为T)中出现,就返回它的具体位置,否则返回-1(常用手段)。

 

思路:两个字符串,如果字符相等,i,j往后移一位;不相等时,i往后移一位,j归0,继续这个循环直到结束

 

package Kmp;

public class kmpBL {
  public static void main(String[] args) {
	 String t="abcccd";
	 String p="ccd";
	 System.out.println(kmp_index(t,p));
}
    public static int kmp_index(String ts,String ps){
    	char[]tt=ts.toCharArray();
    	char[]ss=ps.toCharArray();
    	int i=0; 
    	int j=0;
    	while(i<tt.length&&j<ss.length){
    		if(tt[i]==ss[j]){
    			i++;
    			j++;
    		}
    		else{
    			i=i-j+1;
    			j=0;
    		}
    	}
    	if(j==ss.length) return i-j;
    	else return -1;
    }
}

 

 二:kmp解法

        相等时i,j都往后移一个,不相等时j移动到适当位置,而不是暴力那种,适当的位置就是next数组了

1.1 求next数组思路:

 字符串下标从0开始,next[0]=-1

 比如字符串  ababaabab

 

字符串 aab abaababababaababaaababaabababaabaababaabab
next[j]-1   0  0  1    2    3     1       2       3

 

1.2 求next数组代码:

public static int[] getNext(char[] t){
	  int []next=new int[t.length];
	  next[0]=-1;
	  int j=0;
	  int k=-1;
	  while(j<t.length-1){
		  if(k==-1||t[j]==t[k]){
			  next[++j]=++k;
		  }
		  else{
			  k=next[k];
		  }
	  }
	  return next;
  }

2.1 对next数组改进:nextval数组

还拿上边的字符串求nextval数组:

字符串  ababaabab

    

字符串aababaababababaababaaababaabababaabaababaabab
next[j]-10  0  1  2   3      1      2     3
nextval[j]-10  -1   0  -1    3     0      -1      0

nextval数组求解方法:

                                            

第0个字符是a,next[0]=-1,nextval[0]=-1

第1个字符是b,next[1]=0,然后找0处字符,为a,ab不相等,所以nextva[1]为0

第2个字符是a,next[2]=0,然后找0处字符,为a,aa相等,到边界0了,再往前找就没了,所以nextval[2]为-1

 具体方法就是:当前字符对应的next数组的值 为 当前字符往前回溯的字符下标,如果相等,继续往前回溯,直到不相等或边界为止,nextval值就是当前最后一次相等的next值或者边界值;如果第一次就不相等nextval值就是当前next值

2.2 求nextVal数组代码

 

public static int[] getValNext(char[] t){
		  int []nextVal=new int[t.length];
		  nextVal[0]=-1;
		  int j=0;
		  int k=-1;
		  while(j<t.length-1){
			  if(k==-1||t[j]==t[k]){
				  ++j;
				  ++k;
				  if(t[j]==t[k]) nextVal[j]=nextVal[k];
				  else nextVal[j]=k;
				  
			  }
			  else{
				  k=nextVal[k];
			  }
		  }
		  return nextVal;
	  }

 3. kmp算法代码(nextVal数组实现):

package Kmp;

import java.util.Scanner;

public class kmp1 {
	public static int[] getValNext(char[] t){
		  int []nextVal=new int[t.length];
		  nextVal[0]=-1;
		  int j=0;
		  int k=-1;
		  while(j<t.length-1){
			  if(k==-1||t[j]==t[k]){
				  ++j;
				  ++k;
				  if(t[j]==t[k]) nextVal[j]=nextVal[k];
				  else nextVal[j]=k;
				  
			  }
			  else{
				  k=nextVal[k];
			  }
		  }
		  return nextVal;
	  }
	  public static int kmp_Index(char[]s,char[]t){
		  int []next=getValNext(t);
		  for(int i=0;i<next.length;i++)
			  System.out.println(next[i]);
		  int i=0;
		  int j=0;
		  while(i<=s.length-1&&j<=t.length-1){
			  if(j==-1||s[i]==t[j]){
				  i++;
				  j++;
			  }
			  else{
				  j=next[j];
			  }
		  }
		  if(j<t.length) return -1;
		  else return i-t.length;
	  }
  public static void main(String[] args) {
	  Scanner scan=new Scanner(System.in);
	  while(scan.hasNextLine()){
		  String s=scan.nextLine();
	      String t=scan.nextLine();
	      char[]ss=s.toCharArray();
	      char[]tt=t.toCharArray();
	      if(kmp_Index(tt,ss)==-1)
	    	  System.out.println("NO");
	      else 
	    	  System.out.println("YES");
	  }
	  
}
  
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼爱吃火锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值