KMP算法

文本串:aabaabaaf

模式串:aabaaf

  • 前缀:包含首字母,但是不包含尾字母的所有连续子串

以模式串作为例子:

a

aa

aab

aaba

aabaa

  • 后缀 :只包含尾字母,不包含首字母的所有的连续子串

以模式串作为例子:

f

af

aaf

baaf

abaaf

如何求最长相等前后缀长度 ?

以模式串(aabaaf)作为例子:

a : 0

aa: 1

aab : 0

aaba: 1

aabaa:2

aabaaf : 0

前缀表是模式串用来回退的,它记录了模式串与文本串不匹配的时候,模式串应该从哪里开始重新匹配

前缀表里面存放的是最长相等前后缀的长度

用上面的例子,前缀表就是 010120

当模式串aabaaf与文本串在f的位置匹配冲突时, 去找最长前后缀相等的长度 ,长度就是需要跳转的下标

next数组 :里面存放的元素就是前缀表 ,可能会对前缀表进行调整,具体例子具体分析

按照前后缀的定义来说,一个字符是没有前后缀的,至少得有两个字符才能比较前后缀的异同
如果是两个字符,前缀末位下标就是0,后缀末位下标就是1

leetcode28题为例

cpp 复制代码
class Solution 
{
public:
    void getNext(vector<int> &next, const string& s) 
    {

        //按照前后缀的定义来说,一个字符是没有前后缀的,至少得有两个字符才能比较前后缀的异同
        //两个字符,前缀末位下标就是0,后缀末位下标就是1

        //初始化
        int j = 0;
        next[0] = j;
        for (int i = 1; i < s.size(); i++)
        {
            // 前后缀不同
            while (j > 0 && s[i] != s[j]) 
            {
               // j向前回退
                j = next[j - 1];
            }
            //相同的前后缀
            if (s[i] == s[j])
            {
                j++;
            }
            // 将j(前缀的长度)赋给next[i]
            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) 
    {
        if (needle.size() == 0)
        {
            return 0;
        }
        vector<int> next;
          next.resize(needle.size());
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) 
        {
            while (j > 0 && haystack[i] != needle[j]) 
            {
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) 
            {
                j++;
            }
            if (j == needle.size())
            {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }
};

如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注
你们的每一次支持都将转化为我前进的动力!!

相关推荐
承渊政道几秒前
【动态规划算法】(似包非包以及卡特兰数问题深入解析)
数据结构·c++·学习·算法·leetcode·动态规划·哈希算法
kyriewen114 分钟前
你的前端滤镜慢得像PPT?用Rust+WebAssembly,一秒处理4K图
开发语言·前端·javascript·设计模式·rust·ecmascript·powerpoint
小杍随笔4 分钟前
【Tauri 2 + Rust 配置 WebView2 缓存数据存储到安装目录】
开发语言·后端·rust·tauri
fangzt20109 分钟前
从零搭建自动驾驶中间件(四):数据录制与回灌——算法调试的核心基础设施
算法·中间件·自动驾驶
楼田莉子11 分钟前
仿Muduo的高并发服务器:基于Tcp协议的回显服务器
linux·服务器·c++·后端
人道领域11 分钟前
【LeetCode刷题日记】二叉树层序遍历完全指南:从基础到LeetCode实战一篇搞定BFS模板,秒杀4道经典面试题
java·开发语言·数据结构·leetcode·面试·二叉树
孬甭_14 分钟前
预处理详解
c语言·开发语言
搬砖的小码农_Sky17 分钟前
比特币区块链:SHA256哈希函数
算法·区块链·哈希算法
CSCN新手听安25 分钟前
【Qt】系统相关(二)鼠标事件的处理,鼠标的按下,释放,双击,移动,滚轮滚动事件的处理
开发语言·c++·qt
承渊政道26 分钟前
【动态规划算法】(一文讲透二维费用的背包问题)
数据结构·c++·学习·算法·leetcode·动态规划·哈希算法