字符串匹配(BF,BM,Sunday,KMP算法解析)

字符串匹配一直是计算机领域热门的研究问题之一,多种算法层出不穷。字符串匹配算法有着很强的实用价值,应用于信息搜索,拼写检查,生物信息学等多个领域。
今天介绍几种比较有名的算法:
1. BF
2. BM
3. Sunday
4. KMP

—,BF算法
BF(Brute Force)算法又称为暴力匹配算法,是普通模式匹配算法。

其算法思想很简单,从主串S的第pos个字符开始,和模式串T的第一个字符进行比较,若相等,则主串和模式串都后移一个字符继续比较;若不相同,则回溯到主串S的第pos+1个字符重新开始比较。
依次类推,直到模式串T中每个字符依次和主串S中的一个连续字符串全部相等时,则匹配成功,返回模式串T的第一个字符在主串S中的位置;若主串遍历完也没有成功,则匹配失败。

算法步骤如下:

下标i    0  1  2  3  4  5  6  7  8  9  
主串S    a  b  a  b  c  a  b  c  a  c  
模式串T  a  b  c  a          

第一次比较,从左到右,S[0] = T[0],计数器++;比较S[1] = T[1],i++;当s[2] != T[2],主串回溯,从S[1]重新开始比较。

下标i    0  1  2  3  4  5  6  7  8  9  
主串S    a  b  a  b  b  a  b  c  a  c  
模式串T     a  b  c  a          

也就是说,主串i从0开始,每次比较失败i++,重新比较,直到

下标i    0  1  2  3  4  5  6  7  8  9  
主串S    a  b  a  b  b  a  b  c  a  c  
模式串T                 a  b  c  a   

i = 5,匹配成功。返回 i=5。

可推得,BF算法在最坏情况下需要比较,主串长度M 乘以 模式串长度N, 为-O(M * N)。

代码实现如下:

int BF(const char *str1, const char *str2)
{
    int str1_len = strlen(str1);
    int str2_len = strlen(str2);
    int i = 0;
    int j = 0;

    if(str1 == NULL || str2 == NULL){
        return -1;
    }

    while(i < str1_len && j < str2_len){
        if(str1[i] == str2[j]){
            i++;
            j++;
            //相等则继续逐个比较
        }
        else{
            i = i -j + 1;
            j = 0;
            //不相等则主串回溯,重新比较
        } 
    }
    if (j == str2_len){

        return i - j;
    }else{
    return -1;
    }
}

BF算法简单易懂,但是这个算法效率很差,原因在于每次失败后回溯,浪费了之前的比较,导致了很多次的无用比较,时间损耗较大。

二,BM算法
BM(Boyer Moore)算法是1977年,Robert S.Boyer和J Strother Moore提出了一种在O(n)时间复杂度的匹配算法。时间复杂度要低于BF。

BM算法之所以能够在模式匹配中有更高的的效率,主要是因为BM算法构造了两个跳转表,分别叫做 坏后缀表 ,和 好后缀表 。这两个表涉及了BM算法中的两个规则:

坏字符规则:当文本串中的某个字符跟模式串的某个字符不匹配时,我们称文本串中的这个失配字符为坏字符,此时模式串需要向右移动,移动的位数 = 坏字符在模式串中的位置 - 坏字符在模式串中最右出现的位置。此外,如果”坏字符”不包含在模式串之中,则最右出现位置为-1。

好后缀规则:当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为-1。

算法步骤如下:
1. 首先,”文本串”与”模式串”头部对齐,从尾部开始比较。”S”与”E”不匹配。这时,”S”就被称为”坏字符”(bad character)

  • 12
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值