字符串匹配——BF算法,RK算法(暴力求解)(C/C++)

字符串匹配

问题描述:在主串S中寻找模式串T第一次出现的位置,并返回这个位置。


字符串匹配的暴力搜索方法——BF算法

使用最简单的方法,将模式串与主串进行逐位的比较。

每次偏移量固定设为1,偏移发生在每次失配之后。

代码描述如下:

#include <iostream>
#include <cstring>
using namespace std;

// 使用BF暴力搜索
// 逐字符比较主串S中第一个出现的子串T,返回T出现的第一个位置
// 找不到返回-1
int BFstring(char *S, char *T){
    int lenS = strlen(S);  // 每个串的长度都需要用到
    int lenT = strlen(T);
    int i,j;
    for(i=0;i<lenS;++i){
        for(j=0;j<lenT;j++){  // 逐字符比较
            if(S[i+j]!=T[j])  // 出现不匹配
                break;        // 退出这一轮比较,模式串右移一位
        }
        if(j==lenT)  // 当不匹配退出时,j不等于模式串长度!
            return i;
    }
    return -1;  // 退出循环没有返回位置,意味着没有找到返回-1
}

字符串匹配的另一种暴力算法——RK算法

使用哈希函数,使得可以快速判断当前模式串与主串的待匹配子串是否有可能相等。

哈希函数描述:对模式串或子串(主串的待匹配串)逐字符求和,然后取模使其产生哈希冲突的概率降低。

如若为01串,则直接求和即可。
如若为数字串,则求和取模,模数按数字的范围和串长定,一般模26即可。
如若为字符串,则先将字符转换为数字(ASCII码?),然后求和取模,模数一般设置为26即可。

代码描述如下:

#include <iostream>
#include <cstring>
using namespace std;

int BKstring(char *S, char *T){
    int lenS = strlen(S);
    int lenT = strlen(T);
    int hashS(0),hashT(0),i,j;
    // 初始化哈希值
    for(int k=0;k<lenT;k++){
        hashS += (S[k] - 'a');  // 假设为串为全小写字母的串
        hashT += (T[k] - 'a');
        hashS %= 26;
        hashT %= 26;
    }
    // printf("hashT: %d\nhashS: ",hashT);
    // 比对
    for(i=0;i<=lenS-lenT;++i){
        // printf("%d, ",hashS);
        if(hashS == hashT){
            int flag=1;
            for(int k=0;k<lenT;k++){
                if(S[i+k]!=T[k]){
                    flag = 0;
                    break;
                }
            }
            if(flag)
                return i;
        }
        // 不匹配更新hashS
        hashS -= (S[i] - 'a');
        hashS += (S[i+lenT] - 'a');
        hashS %= 26;
    }
    // putchar('\n');
    return -1;
}
posted @ 2022-03-25 16:53  ymj68520  阅读(428)  评论(0)    收藏  举报
分享到: