【字符串匹配算法】—— BF、RK

本文深入探讨了两种字符串匹配算法:暴力解法(BF)和Rabin-Karp算法。通过实例详细解析了每种算法的工作原理,包括如何在主串中查找模式串,以及Rabin-Karp算法中哈希值的计算和比较过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串匹配

给定两个字符串A和B,判断B是否是A的字串,并返回B在A中第一次出现的位置。
如:
在这里插入图片描述
在上图中B是A的字串,B第一次在A中出现的位置下标是2,则返回2。
为了方便说,就把A串叫主串,把B串称模式串。

BF(暴力解法)

public class Main{ 

    public static void main(String[] args) {
    	String A = "aayaaaaarb";
    	String B = "rbc";
    	System.out.print(solve(A,B));
    }
    
  
    public static int solve(String A, String B){
    	if(A.length() < B.length())  return -1;  //如果模式串大于主串
    	int flag[] = new int[A.length()];  //用来记录模式串的首位在主串中的下标
    	int count = 0; 
    	for(int j=0;j<A.length();j++){//循环找模式串首位在主串的下标
    		if(B.charAt(0) == A.charAt(j)) { 
    			count++;
    			flag[count] = j; 
    		}
    	}
    	
    	for(int i=1;i<count+1;i++){
    	   if(flag[i] + B.length()  > A.length())  return -1;
	       String str =  A.substring(flag[i],flag[i]+B.length());
    	   if(B.equals(str))  return flag[i];
    	}
		return -1;
    }  
}

RK(RabinKarp )

思路:相对于逐个字符比较两个字符串,仅比较两个字符串的hashcode(哈希值)要容易得多。这里哈希值按照‘a’为1,‘b’为2…这样相加得到。当然哈希值相等并不代表匹配成功,比如abc与acb哈希值相等;
还需进一步利用equals()逐个字符比较两字符串。

public class Main{ 
    public static void main(String[] args) {
    	String A = "aayaaaaarbcvv";
    	String B = "rbc";
    	System.out.print(solve(A,B));
    }
     
    public static int solve(String A, String B){
    	//先算出主串中与模式串等长的哈希值,如果相等
        //再将串与模式串比较
    	int n = A.length(); //主串的长度
    	int m = B.length();  //模式串的长度
    	int patternCode = hash(B); //模式串的hash值
    	int strCode = hash(A.substring(0,m));  //求主串的局部哈希值
    	for(int i=0;i<n-m+1;i++){
    		if(patternCode == strCode && compare(i,i+m,A,B))  return i;
    		else if(i<n-m){
    		  strCode = nexthash(A,strCode,i,i+m);
    		}
    	}
		return -1;
    }


	private static int nexthash(String A, int strCode, int i, int j) {
		strCode -= A.charAt(i)-'a';
		strCode += A.charAt(j)-'a';
		return strCode;
	}

	private static boolean compare(int i, int j, String b, String b2) {
		return b.substring(i, j).equals(b2);
	}

	private static int hash(String str) {
		int hasdcode=0;
		for(int i = 0; i < str.length(); i++){
			hasdcode += str.charAt(i)-'a';
		}
		return hasdcode;
	}  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值