网站建设的科目,哈尔滨关键词优化效果,网站的优点和缺点,网页禁止访问怎么办给两个字符串#xff0c;TAAAAAAAAB#xff0c;PAAAAB; 可以暴力匹配#xff0c;但是太费时和效率不太好。于是KMP问世#xff0c;我们一起来探究一下吧#xff01;#xff01;#xff01;
#xff08;一#xff09;最长公共前后缀 D[i] p[…给两个字符串TAAAAAAAABPAAAAB; 可以暴力匹配但是太费时和效率不太好。于是KMP问世我们一起来探究一下吧
一最长公共前后缀 D[i] p[0]~p[i] 区间前i1个字母所拥有的最大......的长度 D[0]0,表示p[0]~p[0]区间前1个字母-也就是 A 所拥有的最长公共前后缀长度为0.D[1]1,表示p[0]~p[1]区间前2个字母-也就是 AA 所拥有的最长公共前后缀长度为1.D[2]2,表示p[0]~p[2]区间前3个字母-也就是 AAA 所拥有的最长公共前后缀长度为2.D[3]3,表示p[0]~p[3]区间前4个字母-也就是 AAAA 所拥有的最长公共前后缀长度为3.D[4]0,表示p[0]~p[4]区间前5个字母-也就是 AAAAB 所拥有的最长公共前后缀长度为0.
我们先手算好了PAAAAB的D[i]数组记录最长公共前后缀继续挖掘看看有没有好东西
1举个栗子T AAAAAAAABPAAAAB D[i]数组上文已经求出 当 i 4,j 4 时T串 和 P串 发生不匹配此时我们就发现 T[0-3] 和 P[0-3] 是完全匹配的那就会思考是否可以用一些方法来跳过已经判断是能匹配的范围呢
在 j 4时j-13D[3] 3,也就是意味着P[0]~P[3] 区间前4个字母所拥有的最大公共前后缀长度为3.
于是从图中我们可以看到标注为① ② ③ ④ 条红色的线表示 T 和 P的前后缀相同 着重看②和③这两条我们可以让 j 3即进行操作是j D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。 此时 i 4 , j 3时T[4] P[3],是匹配的那么让 i, j可得到下图 此时 i 5 , j 4时T[5] ≠ P[4],是不匹配的此时跟前面的操作一样。进行操作是j D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图 此时 i 5 , j 3时T[5] P[3],是匹配的那么让 i, j可得到下图 此时 i 6 , j 4时T[6] ≠ P[4],是不匹配的此时跟前面的操作一样。进行操作是j D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图 此时 i 6 , j 3时T[6] P[3],是匹配的那么让 i, j可得到下图 此时 i 7 , j 4时T[7] ≠ P[4],是不匹配的此时跟前面的操作一样。进行操作是j D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图 此时 i 7 , j 3时T[7] P[3],是匹配的那么让 i, j可得到下图 此时 i 8 , j 4时T[8] P[4],是匹配的那么让 i, j可得到下图 此时 i 9越界, j 5越界终止 总结发现已经匹配成功的部分它所拥有的最大公共前后缀就不用重复进行比较了不用再花费无效的时间进行比较了最大公共前后缀越长那它所省略的就越多效率也就越高。相对于暴力匹配来说效率提升也就越高。
kmp核心思路的关键所在
1.必须理解 D[j] 的意义:P串的前 j1个字母,即 P[0]~P[j] 所拥有的最大公共前后缀2.匹配到T[i] ! P[j]失败时,想一想P[j]是不是P串的第j1个字母,是不是也意味着:P[0]~P[j-1]的这前j个字母已经匹配成功了3.P[0]~P[j-1]的这前 j 个字母的最大公共前后缀 D[j-1] ----来自B站Up邋遢大王233的评论区回复 二KMP Code
D[i] P[0]至P[i]P串前 i1 个字母拥有的最大公共前后缀的长度 D[k] 表示 P[0]~P[k]时前 k1 个 字母拥有的最大公共前后缀的长度
同理D[j-1] P[0]~P[j-1] 前 j 个 字母拥有的最大公共前后缀的长度 结合上图D[j-1]P[0]~P[j-1]前 j 个 字母拥有的最大公共前后缀的长度
在上图我们知道在 i 位置的 x 和 j 位置的 y 匹配失败。此时该怎么办呢为了更好的观察规律我们不妨设D[j-1] 3也就是说P[0]~P[j-1]前 j 个 字母拥有的最大公共前后缀的长度为3。此时如下图 那么让 j D[j-1] 3此时 j 的位置 更新到下标为3这个位置再从j 3这个位置与 T 串的 x进行匹配判断 若 j 0时匹配失败。此时再让 j D[j-1]是无意义的。已经越界了。那怎么办呢 若 j 0时匹配失败。让 j 不变i
j np (视频中没有介绍后续如何继续匹配所以一旦匹配成功一次就结束算法了)。而匹配失败时j只可能减少不可能增加第一次匹配成功后后续想要继续的话继续 j D[j-1] 就可以了(此时必然 j np ,所以写成 jD[np-1] 也对) ----来自B站Up邋遢大王233的评论区回复
未完待续明天继续编辑~
参考和推荐视频kmp_5_最大公共前后缀代码实现_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1iJ411a7Kb?p5vd_sourcea934d7fc6f47698a29dac90a922ba5a3