美文网首页
算法—字符串匹配RK算法

算法—字符串匹配RK算法

作者: 土豆骑士 | 来源:发表于2020-04-28 22:28 被阅读0次

有一个主串S = {a, b, c, a, c, a, b, d, c}, 模式串T 式串在主串中第一次出现的位置;
提示: 不需要考虑字符串大小写问题, 字符均为小写字母。

RK核心思想:

1:将比较复杂的字母串比较,转化为数字比较,模式串T使用特定的哈希公式转化为数字,主串S切分等大小的小串也转化为数字,然后进行数字对比。
2:遍历对比过程中,一边转为为数字,一边进行比较,匹配到了就直接break,减少后续未遍历的转化。


RK核心思想1

RK算法核心思想问题一:如何将模式串或者主串拆分后的子串换算成一个哈希值?

类比三位数数字的加法拆分,转化为10进制的次方加法运算。
针对主串子串的小写字母,我们可以设计相应的哈希函数,转化为26进制的加法拆分。

657=?+?
将‘当前字母’ - 'a' = 数字 ==> 'b' - 'a' = 1; 'c' - 'a' = 2;
结合26进制的推想可以转化如下:
字母转化为数字
字母串转化示例:
字母串转化示例
以上得到了字母串转化为数字的哈希公式
假设当前字母为x,子串length=m, d=26(26进制),sum = 0,
公式为:sum = sum +(x-'a') *d^(m-1); 条件:m>0,m--。

RK算法核心思想问题2:子串哈希值求解规律:

相邻的2个子串 s[i] 与 s[i+1] (i表示子串从主串中的起始位置,子串的长度 都为m). 对应的哈希值计算公式有交集. 也就说我们可以使用s[i-1]计算出s[i] 的哈希值;
以数字为例:


数字间的规律

主串分割后的哈希值:St[i+1] = (st[i] - d2 ✖ s[i] ) ✖ d + s[i+m];
由此得到字母串间的规律:


字母串间的规律
int RK1(char *S, char *P) {
    
    int m = (int)strlen(P);//字串len
    int n = (int)strlen(S);//主串len
    
    double A = 0;//待转化的子串数字声明
    double St = 0;
    
//2.求得子串与主串中0~m字符串的哈希值[计算子串与主串0-m的哈希值]
    //循环[0,m)获取模式串A的HashValue以及主串第一个[0,m)的HashValue
    //此时主串:"abcaadddabceeffccdd" 它的[0,2)是ab
    //此时模式串:"cc"
    //cc = 2 * 26^1 + 2 *26 ^0 = 52+2 = 54;
    //ab = 0 * 26^1 + 1 *26^0 = 0+1 = 1;
//
//    for(int i = 0; i != m; i++){
//        //第一次 A = 0*26+2;
//        //第二次 A = 2*26+2;
//        A = (d*A + (P[i] - 'a'));
//
//        //第一次 st = 0*26+0
//        //第二次 st = 0*26+1
//        St = (d*St + (S[i] - 'a'));
//
//    }
    
    // 子串and主串切分的转化为数字
    int tempm = m;
    for (int i = 0; i <m; i++,tempm--) {
           
           A = A + (P[i] - 'a') * pow(d,tempm-1);
           
           St = St + (S[i] - 'a') * pow(d, tempm-1);
    }
    
    double maxH = pow(d, m-1);//d^(m-1)
    for (int i = 0; i <= (n-m); i++) {
        if (A == St) {
            if(isMatch1(S, i, P, m)){//2次判定是否匹配,因为有可能h产生哈希冲突导致A == St
                return i + 1;
            }
        }
        St = (St - (maxH * (S[i] - 'a'))) * d + (S[i+m] - 'a');//套用子串哈希值求解规律
    }
    
    return -1;
}
int main() {
    char *buf="abcababcabx";
    char *ptrn="abcabx";
    printf("主串为%s\n",buf);
    printf("子串为%s\n",ptrn);
    
    int index = RK1(buf, ptrn);
    printf("find index : %d\n",index);
    
    return 1;
}

相关文章

  • 字符串匹配算法

    以下为学习 《数据结构与算法之美 -- 字符串匹配》 的记录。 BF算法 即暴力匹配算法,循环遍历匹配。 RK算法...

  • 字符串匹配算法

    场景:字符串A为主串,字符串B为模式串,比较字符串B是否能够在字符串A中进行匹配? 匹配算法:BF算法和RK算法。...

  • 字符串匹配算法总结

    面写过一篇字符串匹配算法,总共涉及BF算法,RK算法,BM算法,还有一种算法是KMP算法。这几种算法思想和代码我都...

  • 数据结构与算法学习-BF算法和RK算法

    今天学习字符串匹配问题的算法题目的BF算法和RK算法。题目:有一个主串S = {a, b, c, a, c, a,...

  • 字符串匹配 - BF和RK算法

    字符串匹配有很多种算法,今天在这里先介绍两种比较简单的算法:BF 和 RK 算法。之后我们会学习其它更复杂的匹配算...

  • 学习BM算法的姿势

    BM算法简介 BM是字符串搜索算法。 字符串搜索单模式下有BF、RK、BM、KMP算法,其中BF是暴力搜索,RK是...

  • 字符串匹配算法---RK算法

    这个算法不多聊,核心原理为:哈希表(散列表)的应用,直接上代码:

  • 算法—字符串匹配RK算法

    有一个主串S = {a, b, c, a, c, a, b, d, c}, 模式串T 式串在主串中第一次出现的位置...

  • 字符串匹配

    BF算法 暴力匹配算法O(n*m) RK算法 O(n) BM算法 坏字符规则好后缀规则O(m)

  • 字符串匹配

    indexOf 底层就是使用字符串匹配算法 字符串匹配算法很多 BF( Brute Force)算法 暴力匹配算...

网友评论

      本文标题:算法—字符串匹配RK算法

      本文链接:https://www.haomeiwen.com/subject/jkhpwhtx.html