zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    vi里面全局替换
    guanbi selinux
    ntop
    Java:求一个数组中连续子元素最大和
    LeetCode.643. 子数组最大平均数 I
    分治法-最大子数组问题
    Java实现最大连续子数组和
    golang xorm cmd xorm工具使用 reverse 反转一个数据库结构,生成代码
    golang中xorm的基本使用
    xorm入门
  • 原文地址:https://www.cnblogs.com/wuwendongxi/p/14262986.html
Copyright © 2011-2022 走看看