KMP算法

int kmp(const std::string& text, const std::string& pattern)
{
    if (pattern.length() == 0)
        return -1;

    // 建立next数组 (直接以前缀表表示)
    std::vector<int> next(pattern.length());
    {
        next[0] = 0;
        int i = 1; // 用于遍历的指针
        int j = 0; // 最长相等前缀的下一位指针 (也表示当前最长相等前后缀的长度)
        while (i < pattern.length()) {
            if (pattern[i] == pattern[j]) { // 字符相等, 可以组成新的更长前后缀, 递推加一
                j++;
                next[i++] = j;
            } else { // 出现不相等字符
                /**
                 * 既然无法组成更长的前后缀,那么则从已经找到的最长相等前后缀prefix里,
                 * 找prefix本身的prefix,也就是改变最长相等前缀的下一位指针j,尝试看能否与当前字符组成新的前后缀
                 **/
                if (j > 0)
                    j = next[j - 1];
                /**
                 * 说明当前遍历的字符与首个字符就无法构成最长相等前后缀,则直接更新为0
                 **/
                else
                    next[i++] = 0;
            }
        }
    }

    // 模式匹配
    int i = 0;
    int j = 0;
    while (i < text.length()) {
        if (text[i] == pattern[j]) { // 匹配, 主串和模式串指针继续前进
            i++;
            j++;
        } else if (j > 0) { // pattern中间字符失配, 主串指针不回溯, 模式串指针根据next数组更新
            j = next[j - 1];
        } else { // pattern首个字符失配, 主串指针继续前进
            i++;
        }

        if (j == pattern.length())
            return i - j;
    }
    return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值