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

news/2024/10/30 15:26:41/

2023.6.7
KMP给我人脑cpu干烧了┭┮﹏┭┮

第一阶段:最长相等前后缀的引入给暴力解法带来的改善
暴力解法:
needle每次向前推进一位,然后判断是否与haystack中的相应字串对应,如图所示请添加图片描述
当已知needle中不配对位 前面字串 的 最长相等前后缀的长度时,就不需要只向前推动一位,而是直接向前推进x1-x2位,其中x1是(不配对位前面字串的长度),x2是(不配对位前面字串的最长相等前后缀的长度):如图所示
请添加图片描述
这就是为什么KMP算法比暴力配对算法快的原因,KMP算法每次推进多少是根据不配对位前面字串的信息获取到的,而不是无脑向前推进一位,因此能够更快地成功配对。
tips:关于x2不配对位前面字串的最长相等前后缀的长度怎么算,参见随想录。
那么为什么要推进x1-x2位?要说明这个问题,只需要想明白推进小于x1-x2位时是不可能成功配对的。可以自己假设以下,上图中,如果needle向前推进1位以后,成功配对了,这将意味着aabaa这个字串必定存在着长度为4的相等前后缀,这显然与x2=2相矛盾。同理如果needle向前推进2位以后,成功配对了,这将意味着aabaa这个字串必定存在着长度为3的相等前后缀,这显然也与x2=2相矛盾。只有当向前推进3位时,才有成功配对的可能(此时needle中最长前缀与haystack中的最长后缀一定能够对应上,是否能够成功配对取决于后续能否继续全部对应上)。

第二阶段:想明白如下问题,当已知一个字符串及其最长相等前后缀的长度,在当前字符串后面再添加一个字符,如何求新字符串的最长相等前后缀的长度。(为求next数组做准备)
定理一:如过一个s字符串的最长相等前后缀的长度为n,那么在当前字符串后面删除一个字符,新字符串new_s的最长相等前后缀的长度大于等于n-1,证明如图所示:
请添加图片描述
例子中可以看出原本最长相等前后缀的长度为2,删尾后为至少为1,不可能小于1,还存在其他的串s删尾后最长相等前后缀反而增大,可以自己举例。
证明这个定理,首先要理解为什么最长相等前后缀的长度小于等于n+1
定理二:如过一个s字符串的最长相等前后缀的长度为n,那么在当前字符串后面再添加一个字符,新字符串new_s的最长相等前后缀的长度小于等于n+1,当且仅当新加的字符等于s[n]时,等号成立。
证明这个定理,首先要理解为什么新字符串new_s最长相等前后缀的长度小于等于n+1,这个根据定理一,如果新字符串new_s最长相等前后缀的长度大于等于n+2,那么去掉末尾字符后,s最长相等前后缀的长度大于等于n+1,与条件中s字符串的最长相等前后缀的长度为n相矛盾,所以新字符串new_s最长相等前后缀的长度小于等于n+1。其次当且仅当新加的字符等于s[n]时,等号成立这个很好理解。
那么新的问题来了,如果新加的字符不等于s[n],该如何计算new_s的最长相等前后缀的长度:
请添加图片描述
这就跟求next的代码对上了。
因此代码求每一个字符串的最长相等前后缀的长度时是由上一个字串的最长相等前后缀的长度推导出来的。

class Solution:def strStr(self, haystack: str, needle: str) -> int:if not needle:return 0keeper = [0] * len(needle)self.getkeeper(keeper, needle)j = 0for i in range(0, len(haystack)):# print(j)while (j>0) and (haystack[i] != needle[j]):j = keeper[j-1]if haystack[i] == needle[j]:j += 1if j == len(needle):return i - len(needle) + 1return -1def getkeeper(self, keeper, needle):j = 0keeper[0] = 0for i in range(1, len(needle)):while (j>0) and (needle[i] != needle[j]):j = keeper[j-1]if needle[i] == needle[j]:j = j+1keeper[i] = j

http://www.ppmy.cn/news/263535.html

相关文章

电脑如何共享代理到wifi

最简单的方法: 电脑代理后,下载猎豹wifi,开启wifi,就可以共享啦。(但记得下载的时候开任意一个安全软件,不然猎豹wifi会安装金山毒霸捆绑)(火绒拦截了无数次的人如是说)…

WIFI共享精灵

公司很坑爹,没有WIFI,想忙里偷闲用手机看个新闻都不行,经过网上一番搜索,发现了一个好东西:WIFI共享精灵 只要电脑有无线功能就可以用此软件,现在的笔记本电脑都带无线功能吧 下载地址:http://…

笔记本电脑如何开启wifi热点共享

在Win10操作系统,自带了一个功能就是把有线连接的网络以wifi热点共享出去,给使用无线网络连接的设备上网。以前是要安装一个wifi共享软件来实现这一功能,现在完全不需要了。这需要你的笔记本能使用有线上网,即带有RJ45接口&#x…

android wifi传输音乐,让你通过WiFi分享手机上的歌曲,音乐共享软件MyStream十一发布Android版...

MyStream原来是 iOS上的音乐共享应用,十一期间,它将跨出iOS平台,首次推出Android版音乐共享服务。 MyStream和主流的Pandora、Spotify、Turntable.fm、Songza这些音乐分享服务并不一样。它将手机上的本地音乐通过WiFi或蓝牙和周围的设备进行音…

计算机wifi共享usb设备,手机设置wifi热点如何通过usb和电脑共享网络

将手机的移动数据网络共享给电脑使用的话仅需要开启手机WLAN热点,配置好相关SSID及密码参数即可进行共享,其它的设备包括手机、电脑等都可以通过连接你手机建立的Wifi而进行上网,但是手机运营商通常给我们的移动数据流量都是比较少的&#xf…

免费Wifi软件哪个好?

如今关于免费wifi的软件名头众多,要想从中挑选一款实用的,成了不少用户头疼的事情,放眼望去整个软件布局:wifi共享精灵、连我wifi、毒霸免费wifi等三足鼎立,到底哪一个最好使用呢?下面就一起来看一下各类wifi软件的优缺点。 方法/步骤 WIFI共享精灵: 推荐指数:★★★★★ Wifi…

windows不安装wifi共享软件实现wifi共享

在受够了wifi共享软件的网络不稳定和脑残广告之后,终于想着自己写一个wifi共享软件,后来在网上发现有前辈说windows自带了wifi共享服务,然后测试了一把,成功调用windows系统本身的wifi网络共享,在此记录一下&#xff1…

WiFi共享精灵自身存在的优势

网上流行不少关于Wifi的段子,大概要数下面这条最搞笑:看到一家餐厅写着“我们没有Wifi,你最亲近的人就在身边,你却拿着手机。让我们放下它,去感受原始的人类情感吧。”好感动,现在像这样人文的餐厅真的不多…