KMP算法:一种改进的字符串匹配算法

KMP算法的核心思想是利用模式串的重复部分,比如abab是模式串,主串是abacabc,那么当模式串的第二次出现的b字符与主串的第一次出现的c字符相遇时,c与b不等,那么模式串直接回退到第一个a,因为对于模式串自身而言,ab与ab是相等的,而主串是无需回退的。

主体代码如下:
private int[] getNext(String p) {//模式串自己与自己比较
		int len = p.length(),step=0;
		int[] next=new int[len];
		next[0] = 0;
		for(int i=1;i<len;i++) {
			while(step>0&&p.charAt(step)!=p.charAt(i)) {//预判下一个字符是否相等
				step=next[step-1];//不相等则回溯
			}
			if(p.charAt(step)==p.charAt(i)) {
				step++;//相等则最长真前缀字符串长度加一,最长真前缀字符串是等于最长真后缀字符串的
			}
			next[i]=step;//记录到当前字符为止,最长真前缀字符串与最长真后缀字符串的长度值
		}
		return next;
	}
private int KMP_MATCHER(String T,String P) {
		int P_len=P.length();
		if(P_len==0)return 0;
		int T_len=T.length();
		if(T_len<P_len)return -1;
		if(P_len==1) {
			for(int i=0;i<T_len;i++) {
				if(T.charAt(i)==P.charAt(0))return i;
			}
			return -1;
		};
		int[] next=getNext(P);//得到模式串next数组
		int step=0;
		for(int i=-1;i<T_len-1;i++) {
			while(step>0&&P.charAt(step)!=T.charAt(i+1)) {//注意数组下标问题,数组下标是从0开始的,且不可以小于零
				step=next[step-1];//step是最长真前缀字符串的下一个字符,i+1是最长真后缀字符串的下一个字符
			}//一般伪码实现分析用1开始
			if(P.charAt(step)==T.charAt(i+1))step++;
			if(step==P_len) {
				System.out.println("Pattern occurs with shift"+(i-P_len+2));
				step=0;
				return i-P_len+2;//i+1-(P_len-1)
			}
		}
		return -1;
	}

猜你喜欢

转载自blog.csdn.net/GZHarryAnonymous/article/details/85038301