KMP中的一些技巧(°ο°)~ @

来源:互联网 发布:淘宝 prd mrd 模板 编辑:程序博客网 时间:2024/06/08 11:29

1.最小循环节 :

以下是我看的描述最小循环节能让我看懂的一篇博客~~~
先简单介绍一下KMP算法利用 nxt 数组求最小循环节的原理:
这里写图片描述
假设图中的黑色是原来的字符串,现在要求最小循环节,对于nxt[len]来说指的是图中蓝色和黄色的长度,而且蓝色和黄色是相等的,
那么绿色和紫色也是相等的,,对比原串可知紫色跟粉色是相同的子串,那么绿色跟粉色相同,然后对比蓝色跟黄色可知红色跟粉色相同,对比原串,红色跟棕色相同,那么棕色跟粉色相同,不断重复此过程可知若此字符串有最小循环节,那么循环次数一定为len/(len-nxt[len])。
结论:如果len%(len-nxt[len])=0,那么循环次数为len/(len-nxt[len]),否则为1,所以最小循环节就等于len-nxt[len]。在我的写法中应该是len-nxt[len-1],因为我的数组是从0开始循环的。

2.next数组妙用之求前缀后缀中共同出现的子串:

这里写图片描述
如图,假设黑色线来代表字符串str,其长度是len,红色线的长度代表next[len],根据next数组定义易得前缀的next[len]长度的子串和后缀next[len]长度的子串完全相同(也就是两条线所对应的位置)。我们再求出next[len]位置处的next值,也就是图中蓝线对应的长度。同样可以得到两个蓝线对应的子串肯定完全相同,又由于第二段蓝线属于左侧红线的后缀,所以又能得到它肯定也是整个字符串的后缀。
所以要求前后缀中共同出现的子串只用求出len处的next值向下递归,直到为0的时候。即,next[len] , next[next[len]],…….

substr函数:

在做题的时候发现的一个贼厉害的函数,这个是string类型的函数。有两个参数。例如:
#include<bits/stdc++.h>using namespace std;int main(){    string s;    string t;    cin>>s;    t = s.substr(start,len);//这样t就会被赋予s中以start为起始点(从0开始),以len为长度的字符串。    return 0;}

哇,好用的一批~窒息~~~~

原创粉丝点击