【LittleXi】字符串的模式串匹配问题(含KMP)

1.字符串的模式串匹配问题(含KMP)

前置说明,字符串s长度m,模式串p长度n

1.1BF算法

1.1.1利用循环进行暴力匹配,时间复杂度O(mn)

1.2KR(Karp-Rabin)算法

1.2.1利用滑动窗口内容逐一匹配
1.2.2将滑动窗口内的m个字符的比较变为一个哈希值的比较
时间复杂度O(n)

1.3KMP算法
1.3.1匹配思路:

匹配过程中,对于已经匹配好的p串的子串进行重复利用,i指针指向s串,j指针指向p串,正常匹配的话,i++,j++,当发生匹配失败的时候,我们仅仅需要向前移动j指针,即将j指针移动到j之前的那个子串的前缀能匹配后缀的最大长度的位置,那么怎样移动j指针呢?我们可以用一个next[]数组来记录将j往前移动的位置。

void get_next(char next[],string p)
{
    next[0] = 0; next[1] = 0;
    int j = 0; int i = 2;
    while (i <= p.size())
    {
        if (j==0||p[i - 1] == p[j])
        {
            j += p[i - 1] == p[j];
            next[i++] = j;
        }
        else
            j = next[j];
    }
}
1.3.2图片描述:看图顺序为绿色->黑色->紫色->蓝色

绿色:是已经匹配好了的最长公共前后缀
黑色:是正在匹配的字符,并且是那种不匹配的字符
紫色:是不匹配的情况下,向前递归寻找的的可执行的位置
蓝色:是递归寻找到了的可移动到的位置
说明:所有相同颜色框起来的字符串都是相同的
j的位置已经标出来了,右下角空心箭头指的位置是i的位置
在这里插入图片描述

1.3.3KMP匹配思路

在匹配过程中,我们不断向右移动指针i,如果i,j所指向的字符相同,则同时移动j指针,如果指向的字符不同,则利用next数组将j不断向前回溯,直到j指针所指的内容与i相同 || j指向了0位置。当j匹配完了pa模式串之后,我们可以利用i,j的位置找到被匹配的字符的位置。
参考代码:

    for (int i = 0; i < s.size(); i++)
    {
        if (pa[j] == s[i])
            j++;
        else
        {
            while (j != 0 && s[i] != pa[j])
                j = next[j];
            if (s[i] == pa[j])
                j++;
        }
        if (j == pa.size())
        {
            int po = i - j + 2;
            cout << po << endl;
            j = next[j];
        }
    }
@author:LittleXi
bilibili主页
Leetcode主页
github主页
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值