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

字符串匹配

给定两个字符串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;
	}  
}
发布了77 篇原创文章 · 获赞 100 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/S_123789/article/details/104402064