1 条题解
-
0
分析:
该代码运用了 KMP(Knuth-Morris-Pratt)算法,这是一种字符串匹配算法,主要用于高效地在主字符串中查找子字符串的出现位置。在本题中,KMP 算法的核心部分 next 数组(代码中为 nextt)被用于解决找出字符串所有既是前缀又是后缀的子串长度的问题。
解题思路
要找出给定字符串中所有既是前缀又是后缀的子串长度,可利用 KMP 算法中的 next 数组。next 数组记录了字符串中每个位置之前的子串的最长公共前后缀长度。通过不断回溯 next 数组的值,就能找出所有满足条件的子串长度。
解题原理
1.next 数组的构建:KMP 算法的核心在于构建 next 数组。next[i] 表示字符串中前 i+1 个字符组成的子串的最长公共前后缀长度。在构建 next 数组时,使用两个指针 i 和 k,i 用于遍历字符串,k 用于记录当前的最长公共前后缀长度。当 p[k] 与 p[i] 相等时,k 加 1;当不相等时,k 回溯到 next[k - 1] 的位置继续比较,直到 k 为 0 或者找到相等的字符。
2.找出所有公共前后缀长度:在构建好 next 数组后,从 next[len - 1] 开始回溯,不断将 next[k - 1] 的值添加到结果数组中,直到 k 为 0。最后,将字符串的总长度 len 也添加到结果数组中,因为整个字符串本身也是一个既是前缀又是后缀的子串。
实现步骤
1.输入处理:使用 while 循环不断读取输入的字符串,直到文件结束。
2.构建 next 数组:调用 makenextt 函数,传入字符串和其长度,构建 next 数组。
3.找出所有公共前后缀长度:从 next[len - 1] 开始回溯,将 next[k - 1] 的值依次添加到结果数组 ans 中,直到 k 为 0。
4.添加字符串总长度:将字符串的总长度 len 添加到结果数组 ans 中。
5.排序并输出结果:对结果数组 ans 进行排序,然后按升序输出所有既是前缀又是后缀的子串长度。
c++代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N=400005; int nextt[N]; char str[N]; int ans[N]; void makenextt(char p[],int len) { nextt[0]=0; for(int i=1,k=0;i<len;i++) { nextt[0]=0; while(k>0&&p[k]!=p[i]) k=nextt[k-1]; if(p[k]==p[i]) k++; nextt[i]=k; } } int main() { while(scanf("%s",str)!=EOF) { int len=strlen(str); makenextt(str,len); int k=nextt[len-1]; int tot=0; while(k) { ans[++tot]=k; k=nextt[k-1]; } ans[++tot]=len; sort(ans+1,ans+tot+1); printf("%d",ans[1]); for(int i=2;i<=tot;i++) printf(" %d",ans[i]); printf("\n"); } return 0; }
- 1
信息
- ID
- 1752
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者