算法训练 字符串匹配问题

有一源串和一模式串,编写一个算法求源串中和模式串相同的字串的起始下标
例:String s = “bsadbsadbsadasbd”;
String p = “bsad”;
返回0,4,8

思路

方法1:哈希法

1)将模式串按照某一进制转换为一个哈希值
如将“basd”按照31进制转换:
“b” * 31^3 +“a” * 31^2+“s” * 31^1+ “d” * 31^0
2)每次从源串中取模式串同样长度的子字符串计算哈希值
3)如果子字符串的哈希值和模式串的哈希值相等,则匹配成功,否则取下一组计算

代码:
public class 字符串匹配{
	final static long SEED = 31;

	public static void main(String[] args) {
		String s = "ASDASDASD";
		String p = "ASD";
		match(p,s);
	}
	public static void match(String p, String s) { //p为模式,s为原字符串
		long hash_p = hash(p);
		for (int i = 0; i <= s.length() - p.length(); i++) {
			long hash_temp = hash(s.substring(i, i + p.length()));//substring(begin,end)返回下标从begin到end-1的子字符串
			if(hash_temp == hash_p) {
				System.out.println("Match: "+ i);
			}
		}
		
	}
	public static long hash(String str) {
		long hash = 0;
		for (int i = 0; i < str.length(); i++) {
			hash = hash + str.charAt(i) * (long)Math.pow(SEED,str.length() - 1 - i);
		}
		return hash;
	}

}

方法2:尺取法

  • 1)将源串s和模式串p分别存入字符数组s_array和p_array
  • 2)指针i指向待匹配的子串的开始位置(初始指向s_array的第一个元素)
  • 3)指针j指向待比较的字符(初始指向p_array的第一个元素)
  • 4)指针scanner向前扫描(初始指向s_array的第一个元素
  • 5)scanner指向的元素如果和指针j指向的元素相等就继续向前(j也向前),不相等则j重新回起点,i向后移
  • 6)如果j走到头说明找到了一个和模式串匹配的子字符串
代码:
public class 字符串匹配 {
	public static void main(String[] args) {
		String s = "bsadbsadbsadasbd";
		String p = "bsad";
		match(s,p);
	}
	public static void match(String s, String p) {
		char[] s_array = s.toCharArray();
		char[] p_array = p.toCharArray();
		int i = 0;
		int j = 0;
		int scanner = 0;
		while(i <= s_array.length - p_array.length) {
			if(s_array[scanner] == p_array[j]) {
				scanner++;
				j++;
			}
			else {
				j = 0;
				i++;
				scanner = i;
			}
			if(j == p_array.length) {
				System.out.println(i);
				i = scanner;
				j = 0;
			}
		}
	}
}

发布了33 篇原创文章 · 获赞 3 · 访问量 3798

猜你喜欢

转载自blog.csdn.net/qq_43169220/article/details/103092418
今日推荐