【专题训练】字符串
2019-08-06 23:39
429 查看
KMP
相关
- 单个字符串匹配算法,对模式串预处理求出next数组,匹配时是模式串根据next数组进行跳转。
- KMP可用于匹配子串出现的位置,次数。
- 更常见的应用是根据next数组的性质,结合一些思维或者dp。
- \(next[i]\)即表示模式串前\(i\)个字符的最长前缀后缀相等的长度。
也表示该最长相等后缀对应的前缀的末位置,
i=next[i]
就是表示跳到该前缀,常用。 i-nex[i]
则表示前缀[0...i]的循环节大小(若有),i/(i-nex[i])
就是表示循环节个数。
题目
CF471D MUH and Cube Walls
题意
有一面小墙和一面大墙,小墙可上升下降,问在大墙中能匹配多少个。
分析
很裸的可重叠KMP匹配子串个数,因为墙可升可降,即模式串可同加同减,显然不变的是差分数组,对差分数组进行kmp匹配即可,注意特判模式串长度为1的情况。
代码
#include <bits/stdc++.h> using namespace std; const int N=2e5+50; int a ,b ,n,m; int nex ; void init(int s[],int n){ int i=0,j=-1; nex[0]=-1; while(i<n){ if(j==-1 || s[i]==s[j]){ nex[++i]=++j; }else{ j=nex[j]; } } } int kmp(int s[],int n,int p[],int m){ int i=0,j=0; init(p,m); int cnt=0; while(i<n && j<m){ if(j==-1 || s[i]==p[j]){ i++; j++; }else{ j=nex[j]; } if(j==m){ cnt++; j=nex[j]; } } return cnt; } int main(void){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } for(int i=0;i<n-1;i++){ a[i]=a[i+1]-a[i]; } for(int i=0;i<m;i++){ scanf("%d",&b[i]); } for(int i=0;i<m-1;i++){ b[i]=b[i+1]-b[i]; } int ans=kmp(a,n-1,b,m-1); if(m==1){ //注意特判 ans=n; } printf("%d\n",ans); return 0; }
hdu3336 Count the string
题意
近十年前的一道经典题,给定字符串,求所有前缀作为子串出现的次数之和。
分析
根据next数组的性质,我们从后往前枚举前缀,显然当\(s[0...i-1]\)出现一次时,\(s[0...nex[i]-1]\)也出现了一次,因此定义dp状态为\(dp[i]\)表示长度为i的前缀出现的次数,显然转移式为\(dp[i]+=1\),且\(dp[nex[i]]+=dp[i]\)。
代码
#include <bits/stdc++.h> using namespace std; const int N=2e5+50; const int mod=10007; int T,n; char s ; int nex ; int dp ; void init(char *s,int n){ int i=0,j=-1; nex[0]=-1; while(i<n){ if(j==-1 || s[i]==s[j]){ nex[++i]=++j; }else{ j=nex[j]; } } } void solve(int n){ for(int i=n;i>=1;i--){ dp[i]++; dp[i]%=mod; dp[nex[i]]+=dp[i]; dp[nex[i]]%=mod; } } int main(void){ // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--){ memset(dp,0,sizeof(dp)); scanf("%d",&n); scanf("%s",s); init(s,n); solve(n); int ans=0; for(int i=1;i<=n;i++){ ans=(ans+dp[i])%mod; } printf("%d\n",ans); } return 0; }
相关文章推荐
- 字符串 专题训练 · 最长回文子串之Manacher算法
- 轻松python文本专题-判断对象里面是否是类字符串(推荐使用isinstance(obj,str))
- UESTC专题训练
- 【henuacm2016级暑期训练-动态规划专题 B】Coloring Trees
- 字符串训练 ------- UVA 题目401 - Palindromes
- 算法训练 比较字符串
- 算法训练 最长字符串
- 各大计算机公司 笔试及面试 题目 - 专题(字符串 一)
- 【As Easy As A+B - 专题训练-排序】
- 嵌入式linux之高级c语言专题—数组&字符串&结构体&共用体&枚举
- CSU-ACM2017暑期训练3-递推与递归 G - 展开字符串 HDU - 1274
- 递推求解专题训练
- UESTC 数据结构专题训练 K,L,M
- Training4:字符串训练 练习
- 算法训练 字符串变换
- 蓝桥杯 算法训练 字符串变换
- 字符串专题算法
- 1161: 字符串长度(指针专题)
- 轻松python文本专题-单独处理字符串每个字符的方法汇总
- 2014专题训练之动态规划总结