• UVA12604 Caesar Cipher -kmp


    题意:

    给一个字母表s,一个标准串w,一个密文s,问w是否可能在密文的原文中出现且仅出现一次

    详细:

    • 输入:
      ABC
      ABC
      ABCBBBABC
    • 求:
      在串ABCBBBABCCABAAACABBCACCCBCA中问w是否可能在密文的原文中出现且仅出现一次

    思路

    • 因为字母表s长度很小,所以暴力枚举每一种文本串,对每一个串做一次kmp
    • 调了很久的原因:noww数组未清零,导致strlen时长度有误,解决方法:清零或在末尾打上截止符

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn=500003;
    int pos[130],nxt[maxn],ans[maxn],cnt;
    char a[maxn],b[maxn],c[maxn],noww[maxn];
    void getnext(char t[])
    {
    	int i=0,j=-1,lent=strlen(t); nxt[0]=-1;
    	while(i<lent)
    	{
    		if(j==-1||t[i]==t[j]) nxt[++i]=++j;
    		else j=nxt[j];
    	}
    }
    int kmp(char s[],char t[])
    {
    	int i=0,j=0,ans=0,lens=strlen(s),lent=strlen(t);
    	while(i<lens)
    	{
    		if(j==-1||s[i]==t[j]) ++i,++j;
    		else j=nxt[j];
    		if(j==lent) ++ans,j=nxt[j];
    	}
    	return ans;
    }
    int main()
    {
    	int T; scanf("%d",&T);
    	while(T--)
    	{
    		cnt=0;
    		scanf("%s%s%s",&a,&b,&c);
    		int lena=strlen(a),lenb=strlen(b),lenc=strlen(c);
    		for(int i=0;i<lena;++i) pos[a[i]]=i;
    		for(int i=0;i<lena;++i)
    		{
    			for(int j=0;j<lenb;++j) noww[j]=a[(pos[b[j]]+i)%lena];
    			noww[lenb]='';
    			getnext(noww);
    			if(kmp(c,noww)==1) ans[++cnt]=i;
    		}
    		if(!cnt) puts("no solution");
    		else if(cnt==1) cout<<"unique: "<<ans[1]<<'
    ';
    		else
    		{
    			cout<<"ambiguous:";
    			for(int i=1;i<=cnt;++i) cout<<' '<<ans[i];
    			puts("");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    ubuntu+VS code+launch.json+task.json
    C++——运行时类型识别RTTI
    C++——模板
    C++——class类和struct结构体的唯一区别
    C++——右值引用
    C++——智能指针
    身份证号码格式检测
    PHP获取图片主题颜色
    PHP 压缩图片质量
    redis3.2装完后 其它机子访问爆protocol error, got 'n' as reply type byte
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/14262986.html
Copyright © 2020-2023  润新知