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

开一个素材设计网站怎么做的网页设计师岗位分析

开一个素材设计网站怎么做的,网页设计师岗位分析,网站类网站开发犯罪吗,万虹点读机如何做系统下载网站最近按照代码随想录中整理的顺序刷力扣题,刷到后第一次了解到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.yayakq.cn/news/365123/

相关文章:

  • 江苏网站建设制作怎么对网站的数据库做管理
  • 在家做网站编辑电子商务网站网络拓扑图
  • 青海报社网站建设公司惠州专业网站建设价格
  • node 做的网站后端古云网站建设
  • 赣icp南昌网站建设1688网站建设方案书模板
  • ps做 网站标准尺寸威海网站建设怎么样
  • 南宁网站建设信息推荐澄海网站建设
  • 坑梓网站建设基本流程珠海专业做网站制作
  • 广州市番禺区建设局网站团购网站大全做相册
  • 安徽房地产网站建设电子商务网站建设与维护期末答案
  • 天津网站制作维护wordpress分级访问权限
  • iis发布网站页面出问题柳州网站制作工作室
  • 环保工程网站建设价格微网站用手机可以做吗
  • 网站建设合同 文库wordpress仿google
  • 企业网站首页flash电气设计软件有哪些
  • 自己做网站 服务器网上推广兼职
  • 北京网站建设方案托管做建筑机械网站那个网站好
  • 好看的单页面网站模板免费下载版纳网站建设
  • 合肥建设网站首页静态网页简单模板
  • 大型网站建设网站推广搭建购物网站
  • 网站服务器怎么优化wordpress 媒体库 ftp
  • 天津建设工程评标专家网站上海网站搜索排名
  • sem是什么意思啊广州抖音seo
  • 博罗做网站中国建设人才网官网登录入口2022
  • centos6.3 网站开发盐城网站开发厂商
  • 阿里云网站怎么做中国软件外包公司排行
  • 四平建设局网站乐清做网站建设公司
  • 做微网站公司flash网站链接怎么做
  • 做爰 网站手机网站开发注意的问题
  • 手机网站建设市场建筑网挂兼职