1. 程式人生 > >kmp字串查詢演算法

kmp字串查詢演算法

kmp字串查詢演算法

1 普通的字串查詢

普通的字串查詢是遍歷被查詢的字串,然後和key字串進行匹配,如果不一致,則,被查詢的字串+1,繼續向下遍歷。

程式碼如下:

private static void search(String str, String key) {
	char strArr[] = str.toCharArray();
	char keyArr[] = key.toCharArray();
	int i = 0, j = 0;
	int n = 0;
	while (i < strArr.length && j < keyArr.length) {
		n++;
		if (strArr[i] == keyArr[j]) {
			i++;
			j++;
		} else {
			i = i + 1 - j;
			j = 0;
		}
	}
	if (j == keyArr.length) {
		System.out.println(true);
		System.out.println(n);
		System.out.println(i - j + 1);
	}
}

2 KMP查詢

kmp查詢的是和普通唯一不同的是i在遍歷後發現不同的時候的跳躍的個數不是1。

比較難的是next陣列的計算,next陣列計算的時候計算的是最長子字首和最長子字尾的相同字元的數量。

比如,ABABABA,對於第四個字元B,ABAB他的字首是B BA BAB ,字尾是A BA ABA,所以next[4] = 1。

對於next陣列的計算,暫時沒有特別明白。

程式碼如下:

private static void kmpSearch(String str, String key) {
	char strArr[] = str.toCharArray();
	char keyArr[] = key.toCharArray();
	int[] next = getNext(key);
	for (int i : next) {
		System.out.print(i + ",");
	}
	int i = 0, j = 0;
	int n = 0;
	while (i < strArr.length && j < keyArr.length) {
		n++;
		if (strArr[i] == keyArr[j]) {
			i++;
			j++;
		} else {
			i = i + j - next[j];
			j = 0;
		}
	}
	if (j == keyArr.length) {
		System.out.println(true);
		System.out.println(n);
		System.out.println("=====================");
		System.out.println(i - j + 1);
	}
}

public static int[] getNext(String ps) {
	int next[] = new int[ps.length()];
	char[] p = ps.toCharArray();
	next[0] = -1;
	int k = -1;
	int j = 0;
	while (j < ps.length() - 1) {
		// p[k]表示字首,p[j]表示字尾
		if (k == -1 || p[j] == p[k]) {
			++k;
			++j;
			next[j] = k;
		} else {
			k = next[k];
		}
	}
	return next;
}