KMP算法代码和解释

public class TestClass {

	public static void main(String[] args) throws Exception {
		String param = "abcabcdefabcabcf";
		String string="abciepeiabcabeioabcabcdeioabcabcdefabcabcfabcipwkow";
		int[] next = getNext(param);
		for(int i:next){
			System.out.print(i+" ");
		}
		
		int index = findIndex(string, param, next);
		System.out.println("\nindex="+index);
		System.out.println(string);
		int end = index+param.length();
		for(int i=0;i<string.length();i++){
			if(i>=index && i<end){
				System.out.print(string.charAt(i));
			}else {
				System.out.print("-");
			}
		}
	}
	
	/**获取next数组
	 * @param string	模式串
	 * @return
	 */
	public static int[] getNext(String string){
		int count=0;//对获取next数组没用,用来统计获取next数组所要的时间代价
		int lenght = string.length();
		int[] next = new int[lenght+1];//利用比较巧妙的设计,方便生成next数组和查找匹配,下标为0是没用的,真正的数据从下标1开始
		int k=0;//当前next的值
		for(int i=1;i<lenght;i++){//由于第一个字符肯定为0,所以从1开始
			while(k>0 && string.charAt(i)!=string.charAt(k)){//当不相等时
				/*假设:
				 * string:abcabcdefabcabcf
				 * next :0000123000123456?
				 * 由上面可以看到,当最后一个f和下标为7的d(即abcabc'd')不相等时,
				 * 当前的k为6(即倒数第二个c的next值),通过k=next[k],现在k=3,
				 * 这里就发现前3个abc,和倒数第4到倒数第2也是abc,这时如果正序第四个字符(即a)和最后一个字符f相等,
				 * 那么最后一个字符f的next值就是k++(就是4),但是现在不相等,所以继续回退。k=next[3],k就为0了。
				 * 
				 * 
				 *
				 */
				k=next[k];//回退到上一次匹配的地方
				count++;
			}
			if(string.charAt(i)==string.charAt(k)){//如果相等,等k+1
				k++;
			}
			next[i+1]=k;//因为next数组是从1开始,所以i要先+1才能对应上
			count++;
		}
		
		System.out.println("count="+count);
		return next;
	}
	
	
	
	/**长出第一次出现的下标位置
	 * @param string	长串
	 * @param param		短串,模式串
	 * @param next		next数组
	 * @return
	 */
	public static int findIndex(String string,String param,int[] next){
		int count = 0;
		int j=0;
		int i=0;
		int index=-1;
		int len1 = string.length()-param.length();
		
		while(i<len1){
			count++;
			if(string.charAt(i+j)==param.charAt(j)){
				j++;
			}else{
				i+=j-next[j];
				j=next[j];
				
				if(j==0){
					i++;
				}
				
			}
			if(j>=param.length()){
				index=i;
				break;
			}
		}
		System.out.println("\ncount="+count);
		return index;
	}
	
	

}

运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值