再次学习KMP,关于字符串的许多东西快忘光了,惭愧。这次训练5道题,分别是:
hdu 3336 Count the string (理解)
hdu 4763 Theme Section (理解)
hdu 2594 Simpson’s Hidden Talents (合并串)
hdu 3746 Cyclic Nacklace (最小循环节)
zoj 3587 Marlon’s String (模式串T在主串S上的移动)
hdu 3336 Count the string
http://acm.hdu.edu.cn/showproblem.php?pid=3336
大意:求解一个字符串前缀在字符串里出现次数的和。
分析:由KMP算法得到bnext数组,它记录了前缀和后缀相同的长度。(这里的后缀是广义的后缀,不仅仅是字符串末尾,也可以是中间,关键看指针的移动)
因此如果bnext数组(下标1——n)上的值是大于0的,我们加2,等于0的加1。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=2e5+10,mod=10007;
char str[N];
int n;
int bnext[N];
void get_next(){
int i=0,j=-1;
bnext[0]=-1;
while(i<=n){
if(j==-1 || str[i]==str[j]){
bnext[++i]=++j;
}
else j=bnext[j];
}
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d%s",&n,str);
memset(bnext,0,sizeof(bnext));
get_next();
int ans=0;
for(int i=1;i<=n;i++){
if(bnext[i]>0) ans=(ans+2)%mod;
else ans=(ans+1)%mod;
}
printf("%d\n",ans);
}
return 0;
}
hdu 4763 Theme Section
http://acm.hdu.edu.cn/showproblem.php?pid=4763
求解:符合结构EAEBE字符串的E的最大长度。A和B的长度任意。
分析:理解next数组的意义容易解出。
字符串 | |
---|---|
串 | aaaaa |
位置 | -1 0 1 2 3 4 |
next | 0 1 2 3 4 |
.
字符串 | |
---|---|
串 | a b a a c |
位置 | -1 0 1 2 3 4 |
next | 0 0 1 1 0 |
code:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N=1e6+10;
char s[N];
int bnext[N];
void getnext(int len){
int i=0,j=-1;
bnext[0]=-1;
while(i<=len){
if(j==-1 || s[i]==s[j]){
bnext[++i]=++j;
}
else j=bnext[j];
}
}
int main(){
//freopen("cin.txt","r",stdin);