朴素算法和KMP

朴素算法和KMP算法

算法详细描述(点击)

public class 朴素算法 {
	public static void main(String[] args) {
		String str = "BBC ABCDAB ABCDABCDABDE";
		String target = "ABCDABD";
		boolean res = method(str, target);
		System.out.println(res);
	}

	private static boolean method(String str, String target) {
		int i = 0;//str下标
		int j = 0;//target下标
		char[] char_str = str.toCharArray();
		char[] char_tartget = target.toCharArray();
		while (i < char_str.length && j < char_tartget.length) {
			if (char_str[i] == char_tartget[j]) {
				//若该点匹配 则都向后移动一位
				i++;
				j++;
			} else {
				//若不匹配 则i回溯 减去j并加1 j为移动的步数 加1是为了后移一位
				i = i - j + 1;
				j = 0;
			}
		}
		if (j == char_tartget.length) {
			return true;
		} else {
			return false;
		}
	}
}
public class KMPNext {
	public static void main(String[] args) {
		String s="CAABCDABDD";
		String p = "ABCDABD";
		int[] next = getNext(p);
		System.out.println(Arrays.toString(next));
		int num = KMPSearch(s, p, next);
		System.out.println(num);
	}

	public static int[] getNext(String str) {
		char[] char_str = str.toCharArray();
		int[] next = new int[char_str.length];
		// 第一个值为-1 固定
		next[0] = -1;
		int k = -1;
		int j = 0;
		while (j < char_str.length - 1) {
			// char_str[k]表示前缀,char_str[j]表示后缀
			if (k == -1 || char_str[j] == char_str[k]) {
				++k;
				++j;
				if (char_str[j] != char_str[k])
					next[j] = k;
				else
					// 因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,
					// k = next[k] = next[next[k]]
					next[j] = next[k];
				// System.out.println(Arrays.toString(next));
			} else {
				// 不断的递归k = next[k],直到要么找到长度更短的相同前缀后缀,
				// 要么没有长度更短的相同前缀后缀
				k = next[k];
			}

		}
		return next;
	}
	public static int KMPSearch(String s,String p,int[] next) {
		int i=0;
		int j=0;
		char[] char_s = s.toCharArray();
		char[] char_p = p.toCharArray();
		while(i<char_s.length&&j<char_p.length) {
			//如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
			if(j==-1||char_s[i]==char_p[j]) {
				i++;
				j++;
			}else {
			//如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]    
			//next[j]即为j所对应的next值 
				j=next[j];
			}
		}
		if(j==char_p.length) {
			return i-j;
		}else {
			return -1;
		}
	}
}

如果已知next[j] = k,如何求出next[j+1]呢?具体算法如下:
// 1. 如果p[j] = p[k], 则next[j+1] = k + 1;
// 2. 如果p[j] != p[k], 则令k=next[k],如果此时p[j]==p[k],则next[j+1]=k+1,
// 如果不相等,则继续递归前缀索引,令 k=next[k],继续判断,直至k=-1(即k=next[0])或者p[j]=p[k]为止

相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页