字符串匹配算法

字符串匹配算法

解法

  • 暴力求解
  • Rabin-Karp算法
  • 有限自动状态机
  • KMP算法

暴力求解

使用双重循环,先遍历目标字符串target,依次判断从第target.substring(i,i+pattern.length())是否相同即可。

// 暴力求解
public static int vilot(String target,String pattern){
	for(int i = 0;i<target.length() - pattern.length()+1;i++) if(pattern.equals(target.substring(i,i+ pattern.length()))) return i;
	return 0;
}

Rabin-Karp算法

将字符转化成为数字,利用求模操作进行移动

有限自动状态机

将状态机的状态以及转换过程画出,不同的pattern需要不同的有限自动状态机

KMP算法

KMP算法:利用未匹配字符之前的匹配字符的状态进行移动,有效的利用了之前的比较
重点是next数组的构建生成,kmp算法的思想很简单

// kmp算法
public static int kmp(String target,String pattern,int[] next){
	int i = 0;
	int j = 0;
	int index = 0;
	while(i < target.length()){
		if(target.charAt(i) == pattern.charAt(j)){
			// System.out.println("000000");
			i++;
			j++;
			if(j == pattern.length()) return i-j;
		}else{
			int move = 1;
			// if(j > 0) move = j-0-next[j]; 
			if(j > 0) move = next[j]; 
			index += move;
			// System.out.println("move" + move);
			// System.out.println("index" + index);
			i=index;
			j=0;

		}
	}
	return 0;
}
public static int[] getNext(String pattern){
	// i表示子串的长度
	int i = 0;
	int[] res = new int[pattern.length()];
	for(i = 1;i<pattern.length();i++){
		if(i==1) {
			res[i-1] = 0;
			continue;
		}else{
			String str = pattern.substring(0,i);
			// System.out.println(str);
			int left = 0;
			int right = i-1;
			int nex = 0;
			while(left < i-1 && right > 0){
				if(str.charAt(left) == str.charAt(right)){
					nex++;
					left++;
					right--;
				}else{
					break;
				}
			}
			res[i-1] = nex;
		}

	}
	
	return res;
}

All Coding

class Test{
	public static void main(String[] args) {
		String S = "aabaabaabaac";
		String T = "aabaac";
		// int[] next = new int[]{-1,0,0,0,1};
		int[] next = getNext(T);
		for(int i = next.length -1;i>0;i--) next[i] = next[i-1]+1;
		next[0] = 0;
		// print(getNext(T));
		System.out.println(kmp(S,T,next));
		System.out.println(vilot(S,T));
	}
	// 暴力求解
	public static int vilot(String target,String pattern){
		for(int i = 0;i<target.length() - pattern.length()+1;i++) if(pattern.equals(target.substring(i,i+ pattern.length()))) return i;
		return 0;
	}
	// Rabin-Karp算法
	public static int RK(){
		return 0;
	}
	// 有限自动状态机
	// kmp算法
	public static int kmp(String target,String pattern,int[] next){
		int i = 0;
		int j = 0;
		int index = 0;
		while(i < target.length()){
			if(target.charAt(i) == pattern.charAt(j)){
				// System.out.println("000000");
				i++;
				j++;
				if(j == pattern.length()) return i-j;
			}else{
				int move = 1;
				// if(j > 0) move = j-0-next[j]; 
				if(j > 0) move = next[j]; 
				index += move;
				// System.out.println("move" + move);
				// System.out.println("index" + index);
				i=index;
				j=0;
			}
		}
		return 0;
	}
	public static int[] getNext(String pattern){
		// i表示子串的长度
		int i = 0;
		int[] res = new int[pattern.length()];
		for(i = 1;i<pattern.length();i++){
			if(i==1) {
				res[i-1] = 0;
				continue;
			}else{
				String str = pattern.substring(0,i);
				// System.out.println(str);
				int left = 0;
				int right = i-1;
				int nex = 0;
				while(left < i-1 && right > 0){
					if(str.charAt(left) == str.charAt(right)){
						nex++;
						left++;
						right--;
					}else{
						break;
					}
				}
				res[i-1] = nex;
			}
		}		
		return res;
	}
	public static void print(int[] arr){
		for(int i:arr) System.out.print(i + " ");
		System.out.println();
	}
}
posted @ 2020-12-09 09:21  BOTAK  阅读(85)  评论(0编辑  收藏  举报