KMP模板+习题
2017-04-05 23:53
357 查看
博客首文,弱存下KMP模板,之前一直记在本子上,今天翻了下大神带码,自己又打了一遍,顺便上几道例题。orz
附上链接:点击打开链接
附上大神总结:KMP专题
1.HDU1711点击打开链接
裸题一发,不多解释;(然而,第一遍竟然错了)
POJ2406 点击打开链接
题意:找出最长周期串;
解法:利用next数组的性质,N%(N-next[N-1]+1)==0,则子串长度为(N-next[N-1]+1)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <string>
//poj2406
//next[]数组表示的是,前缀字符串相同的个数
//a b a b a b--T=2
//0 0 1 2 3 4
//a b c a b c--T=3
//0 0 0 1 2 3
//a b c d a b--T不存在
//0 0 0 0 1 2
//N%(N-next
)==0
using namespace std;
int f[1000005];
void getfill(string s)
{
memset(f,0,sizeof(f));
for(int i=1; i<s.size(); i++)
{
int j=f[i];
while(j&&s[i]!=s[i])
j=f[j];
f[i+1]=(s[i]==s[j])?j+1:0;
}
}
int main()
{
string s;
while(cin>>s)
{
int i=0;
if(s==".")
break;
getfill(s);
int n=s.size();
if(n%(n-f[n-1]-1)==0)
{
printf("%d\n",n/(n-f
));
}
else
{
printf("1\n");
}
}
return 0;
}
附上链接:点击打开链接
#include <bits/stdc++.h> int f[10000]; using namespace std; void getfill(string s) { memset(f,0,sizeof(f)); for(int i=1;i<s.size();i++) { int j=f[i]; while(j && s[i]!=s[j]) j=f[j]; f[i+1]=(s[i]==s[j])?j+1:0; } } int find(string a,string s) { getfill(s); int j=0; for(int i=0;i<a.size();i++) { while(j&&a[i]!=s[j]) j=f[j]; if(a[i]==s[j]) j++; if(j==s.size()) return i-s.size()+1; } } int main() { string a,s; string s1="You get it",s2="Cry Cry"; while(cin>>a>>s) { int pos=find(a,s); cout << pos << endl; if(pos!=a.size()) cout<< s1 <<endl; else cout << s2 <<endl; } return 0; }
附上大神总结:KMP专题
1.HDU1711点击打开链接
裸题一发,不多解释;(然而,第一遍竟然错了)
#include <bits/stdc++.h> //HDU1711 //AC1 int f[1000010]; int a[1000010],s[1000010],n,m; using namespace std; void getfill(int* s) { memset(f,0,sizeof(f)); for(int i=1;i<m;i++) { int j=f[i]; while(j && s[i]!=s[j]) j=f[j]; f[i+1]=(s[i]==s[j])?j+1:0; } } void find(int* a,int* s) { getfill(s); int j=0; for(int i=0;i<n;i++) { while(j&&a[i]!=s[j]) j=f[j]; if(a[i]==s[j]) j++; if(j==m) { printf("%d\n",i-m+2); return; } } printf("-1\n"); return; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } for(int i=0;i<m;i++) { scanf("%d",&s[i]); } if(m>n) { cout << -1 <<endl; continue; } find(a,s); } return 0; }
POJ2406 点击打开链接
题意:找出最长周期串;
解法:利用next数组的性质,N%(N-next[N-1]+1)==0,则子串长度为(N-next[N-1]+1)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <string>
//poj2406
//next[]数组表示的是,前缀字符串相同的个数
//a b a b a b--T=2
//0 0 1 2 3 4
//a b c a b c--T=3
//0 0 0 1 2 3
//a b c d a b--T不存在
//0 0 0 0 1 2
//N%(N-next
)==0
using namespace std;
int f[1000005];
void getfill(string s)
{
memset(f,0,sizeof(f));
for(int i=1; i<s.size(); i++)
{
int j=f[i];
while(j&&s[i]!=s[i])
j=f[j];
f[i+1]=(s[i]==s[j])?j+1:0;
}
}
int main()
{
string s;
while(cin>>s)
{
int i=0;
if(s==".")
break;
getfill(s);
int n=s.size();
if(n%(n-f[n-1]-1)==0)
{
printf("%d\n",n/(n-f
));
}
else
{
printf("1\n");
}
}
return 0;
}
相关文章推荐
- 洛谷 3375 KMP模板 KMP
- HDU 1358 KMP模板
- 自己的KMP模板
- POJ3461(KMP模板题)
- KMP模板
- HDU--1686(kmp,模板题)
- 扩展KMP模板
- HDU 2087 剪花布条(KMP入门模板题)
- KMP 算法模板
- 3461 Oulipo 计算a中多少个与b匹配的子串 两个KMP模板
- ccpc 2017 网络赛 1004 A Secret (扩展kmp)【模板】
- KMP基础模板- - -看了很多人的模版,总结一下
- KMP模板与详解
- kmp模板
- HDU 3374 String Problem(最大最小表示法模板+KMP+next数组的运用)
- HDU - 3746 Cyclic Nacklace (KMP模板)
- HDU 3613 Best Reward(扩展KMP模板)
- HDU 2087 剪花布条 KMP极其初级之入门题(KMP模板在这里)
- HDU 2087剪花布条(KMP入门模板题)
- KMP,扩展KMP模板