KMP算法 java版本

1 原理 

  参考 《大话数据结构》第5章 串 的第5.7小节 : KMP模式匹配算法


2 java代码

  KMP.java

package leaning.string.KMP;

public class KMP {
	
	
	public static int indexKMP(String source, String target,int pos) {
		/* i 用于主串source当前位置下标值,若pos不为1
		 则从pos位置开始匹配 */
		int i = pos ; 
		
		/* j 用于子串 target中当前位置下标值 */
		int j = 1 ;
		
		/*定义一组next数组*/
		int[] next = new int[IntArrayLength.length];  
		
		/*对target进行分析,得到next数组*/
		next = NextUtil.getNext(target);
		
		// 将source,target字符串变为字符数组
		char[] sourceChar = KMPStringUtil.stringToChar(source);
		char[] targetChar = KMPStringUtil.stringToChar(target);
		
		//若i小于source长度并且target小于target长度,执行循环
		while(i <=source.length() && j <= target.length() ){
			if(j==0 || sourceChar[i] == targetChar[j] ){
				++i;
				++j;
			}else{
				j = next[j] ;
			}
		}
		if( j > target.length() ){
			return i - target.length();
		}else{
			return 0;	
		}
		
		
	}

	public static void main(String args[]) {
		String source = "asdkfjslkfjwejdklfjew8odklfjsdlkfjslkdj";
		String target = "w8odkl";
		int pos = 0;
		int p  = KMP.indexKMP(source, target, pos);
		System.out.println("在位置 " +p + "完全匹配");
	}
}

NextUtil.java

package leaning.string.KMP;

public class NextUtil {
	
	/**
	 * 
	 * 得到next数组 
	 * */
	public static int[] getNext( String targetStr) {
       if(targetStr==null) return null;
       char[] targetModify = KMPStringUtil.stringToChar(targetStr); // 将targetStr字符串改为字符数组
       int length = targetStr.length();
       // 得到next数组
       int i,j;
       i = 1 ;
       j = 0 ;
       int next[] = new int[IntArrayLength.length];
       while( i < length){
    	   if(j == 0 || targetModify[i] == targetModify[j]){ // targetModify[i]表示后缀单个字符, targetModify[j]表示前缀的单个字符 
    		   ++i;
    		   ++j;
    		   next[i] = j ;
    	   }else{
    		   j = next[j]; // 若字符不同,则 j 进行回溯
    	   }
       }
       
	   return next;
	}  

	public static void main(String args[]){
		String targetStr = "ababaaaba" ;
		int next[] = NextUtil.getNext(targetStr);
		for(int i = 0 ; i < next.length ; i++){
			System.out.print(next[i] + " ");
		}
	}

}


IntArrayLength.java

package leaning.string.KMP;

public  class IntArrayLength {
   public  static int length = 255;
}

KMPStringUtil.java

package leaning.string.KMP;

public class KMPStringUtil {
   
	public static char[] stringToChar(String source){
		 
	       /**
	        * 对source进行改造,使其第一位为一个占位符
	        *    source =    a b c d e f g h
	        * targetModify = '' a b c d e f g h 
	        * 
	        * */
	       char[] targetModify = new char[source.length()+1];
	       int length = source.length() ; 
	       for(int i = 0 ; i < source.length() ; i++){
	    	   targetModify[i+1] = source.charAt(i);
	       }
		return targetModify;
	} 
	
}

3 运行结果

  运行 KMP.java 得到下面结果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。它的核心思想是利用已经匹配过的部分信息,尽量减少不必要的比较次数,从而提高匹配效率。 KMP算法的实现主要包括两个步骤:构建next数组和进行匹配。 1. 构建next数组: - 首先,我们需要定义一个next数组,用于存储模式串中每个位置的最长公共前后缀长度。 - 然后,从模式串的第二个字符开始,依次计算每个位置的最长公共前后缀长度。 - 最后,将计算得到的最长公共前后缀长度填入next数组中。 2. 进行匹配: - 在匹配过程中,我们需要维护两个指针:主串指针i和模式串指针j。 - 当主串和模式串的当前字符匹配时,i和j同时向后移动一位。 - 当主串和模式串的当前字符不匹配时,根据next数组的值调整模式串指针j的位置。 - 如果j等于模式串的长度,表示匹配成功,返回主串中匹配的起始位置。 下面是KMP算法Java实现示例: ```java public class KMP { public static int kmp(String text, String pattern) { int[] next = getNext(pattern); int i = 0, j = 0; while (i < text.length() && j < pattern.length()) { if (j == -1 || text.charAt(i) == pattern.charAt(j)) { i++; j++; } else { j = next[j]; } } if (j == pattern.length()) { return i - j; } else { return -1; } } private static int[] getNext(String pattern) { int[] next = new int[pattern.length()]; next[0] = -1; int i = 0, j = -1; while (i < pattern.length() - 1) { if (j == -1 || pattern.charAt(i) == pattern.charAt(j)) { i++; j++; next[i] = j; } else { j = next[j]; } } return next; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值