【数据结构】字符串 模式匹配算法的理解与实现 Brute Force算法(BF算法)与KMP算法 (C与C++分别实现)

#笔记整理
若不了解串的定义,可至:
串(string)的定义与表示 查看

串的模式匹配算法

求子串位置的定位函数 Index(S, P, pos)
求子串的定位操作通常称作串的模式匹配(其中子串P称为模式串)。

算法1:朴素模式匹配算法/简单匹配算法(Brute-Force算法,简称BF算法)

从目标主串 s = “ s 1 s 2 … s n ” s=“s_1s_2…s_n” s=s1s2sn的第一个字符开始和模式串 p = “ p 1 p 2 … p m ” p=“p_1p_2…p_m” p=p1p2pm中的第一个字符比较,若相等,则继续逐个比较后续字符;否则从目标主串s的第二个字符开始重新与模式串p的第一个字符进行比较。依次类推,若从目标串s的第i个字符开始,每个字符依次和模式串p中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,函数返回0。

实现代码:

// ——————————串的定长顺序存储表示————————————————
#define MAXSTRLEN 255     //最大串长
typedef char SString[MAXSTRLEN+1];

// C语言实现
int index(SString s, SString t, int pos){
   
    // t非空, 1 <= pos <= strlen(s)
    int i = pos;
    int j = 0;
    int sLen = strlen(s);
    int tLen = strlen(t);
    while(i < sLen && j < tLen){
   
        if(s[i] == t[j]){
   
            i++;
            j++;
        }else{
   
            i = i - j + 2;
            j = 1;
        }
    }
    if(j >= tLen){
   
        return i - tLen;
    }else{
   
        return 0;
    }
}

// C++实现
int index2(string s, string t, int pos){
   
    // t非空, 1 <= pos <= Strlength(s)
    int i = pos;
    int j = 0;
    int sLen = s.length();
    int tLen = t.length();
    while(i < sLen && j < tLen){
    // s[0]、t[0]为串长度
        if(s[i] == t[j]){
   
            i++;
            j++;
        }else{
   
            i = i - j + 2;
            j = 1;
        }
    }
    if(j >= tLen){
   
        return i - tLen;
    }else{
   
        return 0;
    }
}

源代码:github地址(其中有详细注释)

朴素模式匹配算法的时间复杂度分析
主串长n; 子串长m。可能匹配成功的位置(1 ~ n-m+1)。

  • 最好的情况下,
    第i个位置匹配成功,比较了(i - 1 + m)次,平均比较次数:
    最好情况下算法的平均时间复杂度O(n+m)。
  • 最坏的情况下,
    第i个位置匹配成功,比较了(i * m)次,平均比较次数:
    设 n >> m,最坏情况下的平均时间复杂度为O(n * m)。
算法2:朴素模式匹配算法的改进算法:KMP算法

KMP算法是 D.E.Knuth、J.H.Morris 和 V.R.Pratt 共同提出的,简称KMP算法。该算法较BF算法有较大改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。
当主串的第 i 个字符与子串的第 j 个字符失配时,若主串的第 i 个字符前的 ( k - 1 ) 个字符与子串的前 ( k -1 ) 个字符匹配,则只需主串的第 i 个字符与子串的第 k 个字符开始向后比较即可,i 不必回溯。

为此,定义 next[] 数组,表明当模式中第 j 个字符与主串中相应字符“失配”时,在模式串中需重新和主串中该字符进行比较的字符的位置 k,即 n e x t [ j ] = k next[j] = k next[j]=k
实现代码:

 // KMP,C语言实现
int indexKMP(SString s, SString t
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值