Java数据结构:KMP(看毛片)算法

首先是next()函数,用于求出来每次匹配的移动规律,在此不得不感叹先人的牛逼思维。详情见下:

public class KMP模式匹配算法 {
	static SeqString s = new SeqString("abcdefghijklmnopqrstu");
	static SeqString a = new SeqString("stu");

	public static void main(String[] args) {
		System.out.println(index_KMP(a, 1));
	}

	public static int index_KMP(IString T, int start) {
		int[] next = getNext(T);
		int i = start;
		int j = 0;
		while (i < s.length() && j < T.length()) { // 循环,查找对比
			if (j == -1 || s.charAt(i) == T.charAt(j)) {// 如果匹配字符j=-1表示S[i]!=T[0],子字符串中没有出现相等的项
				i++; // 转下一个 字符 //最喜欢的情况,按照BruteForce算法匹配
				j++; // 每次匹配成功,j+1;
			} else { // S[i]!=T[j]时
				j = next[j]; // 子字符串移动,再次匹配
			}
		}
		if (j < T.length()) { // 匹配失败
			return -1;
		} else { // 匹配成功
			return (i - T.length());
		}
	}

	private static int[] getNext(IString T) { // 用于在子字符串和主字符串匹配过程中失配后,确认子字符串的从何处开始匹配主字符串
		int[] next = new int[T.length()];	//主要是为了求出各个字符对应的k值,k值决定了他们下次移动的位置
		int j = 1;
		int k = 0; // next[]为k在不同j条件下的值
		next[0] = -1;// 第一项为空,设为-1
		next[1] = 0;// 第二项如果不匹配,只能是第一项
		while (j < T.length() - 1) {
			if (T.charAt(j) == T.charAt(k)) { // 如果匹配,子字符串中出现相等的项,可以减少匹配次数
				next[j + 1] = next[j] + 1; //设置下一项的k值
				j++; // 主字符串指针
				k++; // 子字符串指针,与next[j]同时+1,为之后准备
			} else if (k == 0) { // 没有出现相等的项
				next[j + 1] = 0; // 设置他的next[j+1]为0
				j++;
			} else { 	//如果没出现相同的,则k等于由if产生的next[k];
				k = next[k];
			}
		}
		return (next); // 返回next值

	}
}

猜你喜欢

转载自blog.csdn.net/qq_42192693/article/details/82681996