KMP算法 2203 亲和串
来源:互联网 发布:java运行机制 编辑:程序博客网 时间:2024/06/05 06:21
kmp算法
背景:已知字符串a和字符串b,求字符串b在字符串a中首次出现的位置
kmp算法的核心精髓在于求next数组
next数组含义:next[i] 以 i 结尾(不包括 i)的字符串中前缀和后缀最长相等的长度
比如:s = aabcdaabcd
前缀:a、aa、aab、aabc、aabcd ....... aabcdaabc 都是 s 的前缀
后缀:d、cd、bcd、abcd、aabcd ....... aabcdaabc 都是 s 的后缀
next 数组中 next[0] = -1 这个是一定的,可以看做是规定吧
s的next 数组为
i 0 1 2 3 4 5 6 7 8 9
s a a b c d a a b c d
next -1 0 1 0 0 0 1 2 3 4
就比如说 next[8] 的求法:
以8结尾的字符串为 aabcdaab,我们一眼就可以看出前缀和后缀的最长相等长度为3,即aab和aab,如何让计算机自己求呢?
求next[8]的时候,next[0]~next[7]都是已知的,那么我们可以利用next[7]的结果
以7结尾的字符串为aabcdaa,next[7]=2,那么求next[8]时可以直接判断s[7]是否等于s[next[2]]就好了,如果相等,那么next[8]=next[7]+1,如果不相等,那么就要在判断s[7]是否等于s[next[2]],继续下去,直到相等或者到next[0]=-1了,就跳出循环。
这个表达的也许不是很清楚,光看也不可能看懂,也许还是会有一些不动,一边动手,一边摸索明白可以更好地理解。总之一定要记得next数组的含义
求得了next数组,接下来就是要匹配了
比如 a = aabcdaabcd i=0,指向a字符串
b = cdaa j=0,指向b字符串
先是一位一位的判断是否相等,如果相等那么i++、j++
不相等那么j = next[j],继续判断,为什么可以这样呢,因为在第 j 位失配(没有匹配),那说明字符串b从0~j-1和字符串a从i-j~i-1相等,而next[j]=k表示字符串b中0~k-1 和 j-k~j-1 是相等的,那么字符串a从i-j~i-1和0~k-1是相等的,即只要比较a[i]==b[next[j]]是否为true就好
KMP算法的思路就是这样了
思路明白了,多写几道题吧,边写边熟悉,直到自己会了
hdu 2203一道挺水的题,适合学会了KMP算法来写,基本上就是套模板了
亲和串
亲和串的定义是这样的:给定两个字符串s1和s2,如果能通过s1循环移位,使s2包含在s1中,那么我们就说s2 是s1的亲和串。
AABCDCDAAASDASDF
yesno
<span style="font-size:18px;">#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define LL long longusing namespace std;const int maxn = 100000+5;int Next[maxn];void getNext(string s){ Next[0]=-1; Next[1]=0; int ls=s.size(); for(int i=2;i<ls;i++){ if(s[i-1]==s[Next[i-1]]) Next[i]=Next[i-1]+1; else{ int t=Next[i-1]; while(s[t]!=s[i-1]){ t=Next[t]; if(t==-1) break; } Next[i]=t+1; } }}int kmp(string s1,string s2){ int ls1=s1.size(); int ls2=s2.size(); int i=0,j=0; while(i<ls1 && j<ls2){ if(s1[i]==s2[j]) i++,j++; else{ //j=Next[j]; while(s1[i]!=s2[j]){ j=Next[j]; if(j==-1){ i++; j++; break; } } } if(j==ls2) return i-ls2; } return -1;}int main(){ string s1,s2; int ans; while(cin>>s1>>s2){ getNext(s2); //for(int i=0;i<s2.size();i++) cout<<Next[i]<<' ';cout<<endl; s1+=s1; ans=kmp(s1,s2); //cout<<"ans="<<ans<<endl; if(ans==-1) cout<<"no"<<endl; else cout<<"yes"<<endl; } return 0;}</span>
- KMP算法 2203 亲和串
- hdu 2203 亲和串 KMP算法
- HDU 2203亲和串 kmp算法
- HDU-2203-亲和串-kmp算法
- KMP hdu-2203-亲和串
- HDU 2203 亲和串 KMP
- hdu 2203 亲和串 kmp
- hdu 2203 亲和串(KMP)
- 亲和串 - HDU 2203 KMP
- 【KMP】 HDOJ 2203 亲和串
- 【HDU】2203 亲和串 KMP
- Hdoj 2203 亲和串 【KMP】
- hdoj-2203-亲和串【KMP】
- HDU 2203(KMP) 亲和串
- HDU 2203 亲和串 (KMP)
- hdu 2203 亲和串 KMP
- HDU - 2203 亲和串(Kmp)
- HDU 2203 亲和串 KMP
- hdfs 命令行操作
- seaborn ——Jointplot
- 手机蓝牙传输图片很邪恶的一个点
- EVP加密解密编程
- css3实现背景渐变
- KMP算法 2203 亲和串
- 使用shape自定义TextView的三态
- Android Studio下引入jar包
- base64编码原理及简单Python实现
- Android官方文档之Calendar Provider
- 5月份英语学习
- SQL 中GO、EXEC、ON
- 58同城
- Android ViewPager 打造炫酷欢迎页