字符串板子
Posted passione-123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串板子相关的知识,希望对你有一定的参考价值。
上板子
KMP
for(int i=1;i<n;i++){ while(u>0&&s[u]!=s[i]){ u=Pi[u-1]; } if(s[u]==s[i]){ u++; } Pi[i]=u; }
Z Algorithm
for(int i=1,l=0,r=0;i<len;i++){ if(i<=r)Z[i]=min(r-i+1,Z[i-l]); else Z[i]=0; while(s1[Z[i]]==s1[i+Z[i]])Z[i]++; if(i+Z[i]>r){ for(int j=r+1;j<i+Z[i];j++)Pi[j]=j-i+1; r=i+Z[i]-1,l=i; } }
各种用法
//查找子串t在s中出现的位置 int u = 0; for(int i=1;i<m;i++){ while(u>0&&t[u]!=t[i])u=Pi[u]; if(t[u]==t[i])u++; Pi[i]=u; } u=0; for( int i = 0;i < n; i++){ while(u>0&&t[u]!=s[i])u=Pi[u]; if(t[u]==s[i])u++; if(u==m){ printf("%d ",i-m+1); u=Pi[u]; } } //查找每个前缀的出现次数 KMP(s,n,Pi); for (int i = 0; i < n; i++) ans[pi[i]]++; for (int i = n - 1; i > 0; i--) ans[pi[i - 1]] += ans[i]; for (int i = 0; i <= n; i++) ans[i]++; //查找本质不同子串数目 for(int i=0;i<n;i++){ char c;int MAX=0; cin>>c; strcat(s,c);s1=s; reverse(s1,s1+i+1); KMP(s1,i+1,Pi); for(int j=0;j<=i;j++)MAX=max(MAX,s1[j]); ans+=(i-MAX); } //查找b与a的每一个后缀的最长公共前缀 scanf("%s%s",s2,s1); int len1=strlen(s1); int len2=strlen(s2); strcat(s1,"#"); strcat(s1,s2); int len=len1+len2,l=0,r=0; for(int i=1;i<=len;i++){ if(i<=r)z[i]=min(r-i+1,z[i-l]); else z[i]=0; while(s1[z[i]]==s1[i+z[i]])z[i]++; if(i+z[i]>r)r=i+z[i]-1,l=i; } for(int i=0;i<len1;i++){ if(!i)printf("%d ",len1); else printf("%d ",z[i]); } puts(""); for(int i=len1+1;i<=len;i++){ printf("%d ",z[i]); } //字符串压缩 Z Algorithm(s,n,Z); for(int i=1;i<n;i++){ if((n%i==0)&&(z[i]+i==n)){ printf("%d ",i); } }//Z puts(""); KMP(s1,n,Pi); printf("%d",n-Pi[n-1]);//KMP
以上是关于字符串板子的主要内容,如果未能解决你的问题,请参考以下文章
片段(Java) | 机试题+算法思路+考点+代码解析 2023