欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

模式匹配 KMP

程序员文章站 2022-07-14 15:23:44
...

上代码:

next道理懂了,运行过程还是没琢磨明白。

第二个next是优化的算法,还没看懂。

 

package com.test;

public class Test {

	/**
	 * kmp算法,主串指针不回溯的一种算法。时间复杂度可以达到O(n+m)nm是串长度
	 * 关键是要解决:当匹配到模式串的某个字符,发生不匹配之后;主串指针如何向右移动。(next就是解决这个问题)
	 * next返回的是:
	 * 1数组的意义:
	 * 	每个元素代表模式串一个字符,表示当这个字符失配,而前面的字符都匹配时,“主串当前指针要和模式串中的第几个字符继续比较”。
	 * 2这个结果数组的计算方式是:
	 * 	找到模式串当前这个字符紧挨着它前面的连续几个字符和模式串开头连续几个字符是否相等,
	 * 	(1)没有匹配记录0,
	 * 	(2)有匹配记录开头连续几个字符的个数(或者这个连续串的下个下标)。
	 * 	(3)-1代表母串指针需要移动
	 * @author yfchenlei
	 * @date 2012-9-20
	 * @param str 主串
	 * @param sub 子串
	 * @param pos 主串开始位置
	 * @return 
	 */
	public static int kmpIndexOf(String str, String sub, int pos){
		int i = pos;
		int j = 0;
		int[] next = next2(sub);
		while(i < str.length() && j < sub.length()){
			if(j == -1 || str.charAt(i) == sub.charAt(j)){
				i++;
				j++;
			}else{
				j = next[j];
			}
		}
		if(j == sub.length()){
			return i - sub.length();
		}
		
		return -1;
	}
	/**
	 * next算法
	 * @param sub 模式串
	 * @return
	 */
	public static int[] next1(String sub){
		int len= sub.length();
		int[] next = new int[len];
		int i = 0;
		int j = 0;
		while(i < len){
			 next[i] = j -1;
			 if(j == 0 || sub.charAt(i) != sub.charAt(j - 1))
				 j = 0;
			 i++;
			 j++;
		}
		return next;
	}
	/**
	 * 优化next算法
	 * @param sub 模式串
	 * @return
	 */
	public static int[] next2(String sub){
		int[] next = new int[sub.length()];  
		next[0] = -1;  
		int i = 0;  
		int j = -1;  
		while (i < sub.length() - 1) {  
			if (j == -1 || sub.charAt(i) == sub.charAt(j)) {  
				i++;  
				j++;  
				if (sub.charAt(i) != sub.charAt(j)) {  
					next[i] = j;  
				} else {  
					next[i] = next[j];  
				}  
			} else {  
				j = next[j];  
			}  
		}  
		return next; 
	}
	
	public static void main(String[] args) {

	}
}

 。

上一篇: 1.两数之和

下一篇: em-dosbox