【KMP变形求公共子串】HDU 1867——A+B for U again

来源:互联网 发布:nginx ip会话保持 编辑:程序博客网 时间:2024/06/10 13:14

题目:点击打开链接

KMP的常见变形。寻找两个字符串,求这两个子串的叠加串。可以看到公共序列的影子,KMP模板中的返回值变成J就可以过。

WA的常见理由:

1、没有注意到相同不消字母时按字典序排列,样例:efgh abcd 结果:abcdefgh

2、没有注意到kmp(a)=kmp(b)但有重复子串时怎么处理,样例:as sa 结果:asa

3、忘记了反向输出时的情景,例如:asdk qbas 结果:qbasdk

4、其他应该没什么问题了。。

#include <string>#include <iostream>using namespace std;int next[100005];void build_next(string b){ int i,j=0,key=0;    memset(next,0,sizeof(next));    for(i=1;i<b.size();i++)    {        j=next[i-1];        while(j==1 && b[i]!=b[j])        {        j=next[j-1];        }        if(b[j]==b[i])        {            next[i]=j+1;        }        else next[i]=0;    }}int KMP_Find(string s,string t) //pos从0开始,输出绝对位置要加1 {build_next(t);int i=0;int j=0;for(i=0;i<s.size();i++){while(j>0 && s[i]!=t[j]){j=next[j-1];}if(s[i]==t[j]){j++;}else{j=0;}}return j;}int main(){string a,b;while(cin>>a>>b){memset(next,0,sizeof(next));int resa,resb;resa=KMP_Find(a,b);resb=KMP_Find(b,a);if(resa>resb){for(int i=0;i<a.size();i++)cout<<a[i];for(int j=resa;j<b.size();j++)cout<<b[j];cout<<endl;}else if(resb==resa){if(a<b){for(int i=0;i<a.size();i++)cout<<a[i];for(int j=resa;j<b.size();j++)cout<<b[j];cout<<endl;}else{for(int j=0;j<b.size();j++)cout<<b[j];for(int i=resb;i<a.size();i++)cout<<a[i];cout<<endl;}}else{for(int j=0;j<b.size();j++)cout<<b[j];for(int i=resb;i<a.size();i++)cout<<a[i];cout<<endl;}//cout<<resa<<resb<<endl;}return 0;}


原创粉丝点击