携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
求next数组是kmp算法中不可或缺的一步,以next[i]为例,其具体含义为str[1~i]中前缀与后缀能匹配的最长长度。注意这里的前后缀不能是整个字符串,不然的话所有的next[i]都等于i了,没有意义。还有这里的next[i]只是最长的长度,比它小的长度有没有匹配并不确定。
求next数组的模板:
for(int i = 2, j = 0; i <= len; i++)
{
while(j && s[j+1] != s[i])
j = _next[j];
if(s[j+1] == s[i])
j++;
_next[i] = j;
}
目前发现的关于next的有意思的用法:
-
求str[1~len]中所有匹配的前后缀
证明很简单,画图推一下就行,直接上代码。
int t = _next[len]; while(t >= 1)//直到t=0 { cnt++;//记录能匹配的前后缀数量 t = _next[t]; } -
求某个前缀在串中出现(可重叠)次数
结合dp,其中dp[i]表示str[1~i]在整个串出现次数。显然是个刷表的过程,倒序遍历是为了保证使用到dp[i]时它已经被更新完毕。逻辑上也很好理解,对于每一次出现的str1~i都会使dp[next[i]]增加1。
for(int i = 1; i <= len; i++) dp[i]++; for(int i = len; i >= 1; i--) dp[_next[i]] += dp[i];