数据结构——串

BF算法 时间复杂度(O(nm))

一个一个遍历 不多赘述

KMP算法 时间复杂度(O(m+n))

kmp算法有两个点需要注意

点1. 计算模式串的前缀

遍历的时候注意当回到第一个点的时候 或者两点相同的时候 该点的后面一个点等于最大前缀和 

点2. 遍历主串移位

遍历的时候同样注意如果回溯到第一个点,让该点前缀和为0,主串指针右移

如果没回溯到第一个点,那么就用next指针找到当前最大前缀长度,前面重复的前缀不用算,只用看后面不相同的即可

#include <iostream>
using namespace std;
const int N = 100010;
int Next[N];
string a, b;
void getNext(string a)
{
    int j = 0;
    int k = -1;
    Next[0] = -1;
    while (j < a.length() - 1)
    {
        if (k == -1 || a[j] == a[k]) // 如果没找到使得k为-1了 或者下标j和下标k代指的数组相同,那么就让最长相等前后缀继续加1
        {
            Next[++j] = ++k;
        }
        else
        {
            k = Next[k]; // 如果不相同 则 往前找 找到上次匹配到的,与这次有可能有相同前缀的子串
        }
    }
}
int KMP()
{
    int i = 0, j = 0;
    while (i < a.length() && j < b.length())
    {
        cout << j << " " << b[j] << " " << i << " " << a[i] << endl;
        if (j == -1) // 第一位都匹配不到 你就直接往后走吧
        {
            i++;
            j = 0;
        }

        else if (b[j] == a[i]) // 如果相等 指针全部右移
        {
            ++i;
            ++j;
        }
        else // 如果不相等的话,找到该点前面点的前缀和,让指针从前面那个点所在的最大前缀和的点 开始遍历
        {
            j = Next[j];
        }
        cout << i << " " << j << " " << endl;
        //  if (j == b.length() - 1)
        //    break;
        // 注释掉的地方是我画蛇添足了,仔细想一下,在n-1处就能停止了吗?不,应该还要用在n-1处的数值检验一次,对了直到length才能出去
    }
    cout << i << " " << j << endl;
    return i - j + 1;
}
int main()
{
    cin >> a >> b;
    getNext(b);
    KMP();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值