当前位置: 首页 > news >正文

控制面板网站手机网站关键词快速排名

控制面板网站,手机网站关键词快速排名,wordpress用java,网站更新提示ui怎末做最近按照代码随想录中整理的顺序刷力扣题,刷到后第一次了解到KMP算法,看了B站视频,觉得卡哥这集讲的有些精炼,于是自己通过代码理解了一下后,用比较通俗形象的方式,向大家介绍一下KMP算法。 一 什么是KMP算…

最近按照代码随想录中整理的顺序刷力扣题,刷到后第一次了解到KMP算法,看了B站视频,觉得卡哥这集讲的有些精炼,于是自己通过代码理解了一下后,用比较通俗形象的方式,向大家介绍一下KMP算法。

一 什么是KMP算法

KMP算法是由Knuth,Morris和Pratt三位学者发明的,所以取了三位学者名字的首字母,称作KMP算法。
KMP算法主要用在字符串匹配上。
比如我们从字符串"acfacfgded"(需要在哪里找的字符串称为“文本串”)找其中是否包含字符串"acfg"(需要从文本串里找的字符串我们叫做“模式串”),我们一般会想到的解法是暴力求解,两层for循环,依次对模式串的每一个元素进行匹配,如果匹配失败,下次还从模式串的第一个进行匹配,这就导致了较高的时间复杂度(O(n×m))。
而KMP算法不同之处就在于,当模式串的某个元素匹配失败后,不需要再从模式串的第一个元素从头开始匹配了,而是根据前缀表(next)找到模式串中一个最优的位置继续进行匹配

二 什么是前缀表

前后缀

什么是前缀:字符串的前缀是指从第一个元素开始的、不包括最后一个元素的连续字串。
什么是后缀:字符串的后缀是指不包括第一个元素的、以最后一个元素结尾的连续子串。
最长相等前后缀:字符串的最长相等前后缀就是字符串的前缀、后缀中相等的、最长的连续子串。
例如,对于字符串"acdac"。

前缀后缀最长相等前后缀
a、ac、acd、acdacdac、dac、ac、cac

还有一种形象一点的理解,就是你,将一个字符串固定不动,另外一个完全一样的字符串不断向右平移,直到两个字符串的交叉部分的元素相等,相等前后缀就是两个字符串的交叉部分。如"acdac"的最长相等前后缀就是下面这个图
图1

前缀表

前缀表 next ,是一个跟模式串具有同样长度的数组, next 每一个元素 next[i] 记录的是模式串下标 i(包括i)之前的字符串的最长相等前后缀的长度
因此呢,字符串"aabaab"的前缀表就是

010123

上面这个前缀表是原始前缀表,常见的还有另外两种:统一减一、统一右移形式。
字符串"aabaab"的统一减一形式的前缀表是

-10-1012

字符串"aabaab"的统一右移形式的前缀表是

-101012

这三种形式的前缀表没有本质的差别,只是因为代码上的实现不一样导致的区别,我个人更喜欢统一减一形式的,这样子 next[i] 记录的是模式串下标 i(包括 i )之前的字符串的最长相等前后缀的最后元素的下标了

三 前缀表的作用

前缀表在匹配过程中到底有什么用呢?用一个例子来讲解,我们要从文本串 “aabaabaafa” 中找其中是否包含模式串 “aabaaf” 。
首先我们可以得出模式串的前缀表(统一减一形式)是

010120
  1. 首先按正常逻辑我们对文本串和模式串进行匹配,发现到模式串第六个元素,b != f,匹配失败。
    在这里插入图片描述

  2. 当匹配失败时,常规思路是让模式串向右平移一格,接着再从模式串的第一个元素开始匹配。但是在KMP算法中,我们可以利用前缀表,向右平移若干格,且从文本串中匹配失败的位置与模式串再进行匹配。虽然第六个元素匹配失败,但前五个元素是匹配成功的,因此,我们根据前缀表,得到前五个元素的最长相等前后缀的长度是2,这就意味着,我们将模式串向右移若干格之后,能保证使得模式串的长度为2的前缀能跟文本串中匹配失败的前一个位置对齐,最终效果如下图。这样就不用每次都从头开始匹配了。
    在这里插入图片描述

  3. 然后接着将文本串中原先匹配失败的位置与模式串中的刚刚用到的最长相等前后缀的后一个位置进行后续的匹配(这里这个位置的下标恰好就是2!!!这就是一个结论:前缀表的值,就是不匹配之后移动模式串、新的与文本串进行匹配的位置下标!!!

总结

前缀表的作用就是在模式串与文本串匹配失败的时候,不需要一处失败就全盘否定从头开始,而是通过找匹配失败位置前一位的前缀表的值,实现模式串向右移后(通过图来理解),模式串的第 [匹配失败位置前一位的前缀表的值] 位与文本串匹配失败的位置进行新一轮的 匹配。

四 前缀表的构建

可见,前缀表是KMP算法的核心,下面介绍一下前缀表(每个元素是最长前后缀长度)的构建。以下是C++代码举例。

    void getNext(int* next, const string& s) {int j = 0;next[0] = 0;for(int i = 1; i < s.size(); i++) {while (j > 0 && s[i] != s[j]) { // j要保证大于0,因为下面有取j-1作为数组下标的操作j = next[j - 1]; // 注意这里,是要找前一位的对应的回退位置了}if (s[i] == s[j]) {j++;}next[i] = j;}}

这首先定义了两个指针i和j,j指向前缀末尾位置,i指向后缀末尾位置,其实也就是找每个i对应的j是多少。这整个过程像是递归的过程,并且也用到了KMP算法匹配过程的回退思想。

前缀表的构建可分为3步:

  1. 初始化。初始化next[0] = 0,j=0。(for循环的每一轮结束时的j位置对应的前缀,都和i位置的后缀是匹配的,明白这一点非常重要!)

  2. 前后缀不匹配时。for循环的每一轮结束时的j位置对应的前缀,都和i位置的后缀是匹配的,for循环的下一轮开始时,i向右移动了一格,这时候如果 s[i] != s[j] ,这就是前文中的匹配失败的情况,就要找前一位的前缀表的值了,并再跳转到这一位,也就是代码中的

    while (j > 0 && s[i] != s[j]) { // j要保证大于0,因为下面有取j-1作为数组下标的操作j = next[j - 1]; // 注意这里,是要找前一位的对应的回退位置了
    }
    

    之所以是while而不是if,这就是要一直向前回退直到匹配的情况。

  3. 前后缀匹配时。for循环的每一轮结束时的j位置对应的前缀,都和i位置的后缀是匹配的,for循环的下一轮开始时,i向右移动了一格,如果这时候s[i]==s[j],那就是匹配成功了,因为要找的是最长相等前后缀,你就需要j右移。

整个过程大家可以自己举个例子画个图来模拟下一下整个过程,方便自己理解。

五 运用到解题中

力扣 28.找出字符串中第一个匹配项的下标

参考代码

class Solution {
public:void getNext(int* next, const string& s) {int j = 0;next[0] = 0;for(int i = 1; i < s.size(); i++) {while (j > 0 && s[i] != s[j]) {j = next[j - 1];}if (s[i] == s[j]) {j++;}next[i] = j;}}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[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;}
};

不清楚的地方欢迎留言交流

http://www.ritt.cn/news/8956.html

相关文章:

  • 网站优化建设宁夏市场营销策划方案书
  • 西宁手机网站建设市场调研报告万能模板
  • 招聘网站如何做百度seo排名曝光行者seo
  • 汕头网站外包北京网络seo
  • 建站产品怎么推广自己的公司
  • 做透明头像的网站推广官网
  • 类似站酷的网站建站专门做排行榜的软件
  • 上海好的网站设计公司有哪些百度云网盘登录入口
  • 可以做网站AB测的软件一键seo提交收录
  • 怎么通过做网站赚钱吗网络平台运营是做什么的
  • 空壳3年公司转让多少钱东莞网站优化
  • 新建网站怎么做站长统计网站统计
  • 办网站怎么办百度推广上班怎么样
  • 贵州省住房和城乡建设厅网站青岛seo网络推广
  • 织梦模板安装 一品资源网南宁seo推广优化
  • 做网站如何语音白帽seo
  • 江苏建信建设集团网站我想接app注册推广单
  • 自己做的网站如何实现下载文件站外推广怎么做
  • 长沙做最好网站千锋教育怎么样
  • 做网站的关键词怎么判断好不好怎么优化网站
  • 好网站推荐一下如何建立网上销售平台
  • 一流本科专业建设点网站湖北网站推广
  • 急招一对夫妻门卫6500元天津搜狗seo推广
  • 佛山网站搭建如何发布自己的网站
  • 贵阳有哪家做网站建设好点的软文标题大全
  • 顶尖的设计网站九江seo
  • 教育网站官网百度推广的五大优势
  • 烟台网站建设推荐企汇互联见效付款东莞seo整站优化
  • 哪个网站可以做链接sem搜索引擎
  • 重庆比较好的软件开发培训学校seo课程多少钱