求一个字符串的所有前缀的循环节出现的最大次数。也就是最小循环节
kmp算法求循环节;
将原串移动,移动后我们得知,四个黑色大括号完全相同。在下图所示的事例中,原串只有两个循环节,加一个红括号。k3加一个红括号的长度就是kmp中的next数组。
字符串长度-next即为循环节长度。

下面的串向右移动的长度为n-next,而next是最大的前后缀相等的长度。所以移动的长度K是最小的循环节。
上面我们做了什么事:我们根据字符串的next数组的最大值,将其向后移动,使得前后缀重合。
又根据一些特点,(移动前后对应位置相等,前后缀对应相等)得到规律。
但是上面作图的前提是一个串去除了后缀之后的剩余长度。比后缀小。否则构成不了关系。
下面这种情况就不能构成后缀是由某个循环体构成的。

- #include
- using namespace std;
- const int N=1e6+10;
- int n,m;
- char s[N];
- int ne[N];
- //141周期
- int main()
- {
- int T=0;
- while(scanf("%d",&n),n)
- {
- scanf("%s",s+1);
- for(int i=2,j=0;i<=n;i++)
- {
- while(j&&s[i]!=s[j+1])j=ne[j];
- if(s[i]==s[j+1])j++;
- ne[i]=j;
- }
- cout<<"Test case #"<<++T<
- for(int i=1;i<=n;i++)
- {
- int t=i-ne[i];
- if(i%t==0&&i/t>1)cout<" "<
- }
- cout<
-
- }
- }
831 kmp字符串(第一个自己ac的kmp)
还犹豫下午到底还学不学kmp
- #include
- //831 kmp字符串
- using namespace std;
- const int N=1e5+10,M=1e6+10;
- int n,m;
- char p[N];//p和s都是从1开始存
- char s[M];
- int ne[N];//从0开始
- int main()
- {
- cin>>n>>s+1>>m>>p+1;
- //求next数组
- ne[1]=0;
- for(int i=2,j=0;i<=n;i++)
- {
- while(j&&s[i]!=s[j+1])j=ne[j];
- if(s[i]==s[j+1])j++;
- ne[i]=j;//与i当前位置为末尾所代表的后缀
- //与其对应的前缀的末尾位置下标。
- }
-
- //匹配的过程
- for(int i=1,j=0;i<=m;i++)
- {
- while(j&&p[i]!=s[j+1])j=ne[j];
- if(p[i]==s[j+1])j++;
- if(j==n)//已经匹配到最后了
- {
- cout<
" "; - //一定要注意
- j=ne[j];
- }
-
- }
- }
-
相关阅读:
Sentinel流控规则可以这样玩?
使用arduino编写mqtt客户端连接emqx服务器
利用opnet快速构建tree网络
Docker--Harbor私有仓库部署与管理
QPaint绘制自定义仪表盘组件03
【ARM Cache 系列文章 10 -- ARM Cortex-A720 Hunter 介绍】
Flask框架——Flask-SQLite数据库
人工智能底层自行实现篇3——逻辑回归(下)
SpringBoot+若依+图片导出
飞行动力学 - 第33节-螺旋模态机理 之 基础点摘要
-
原文地址:https://blog.csdn.net/qq_61369552/article/details/136599820