您的位置:首页 > 大数据 > 人工智能

HDU_4300 Clairewd’s message(KMP)

2015-08-14 16:50 429 查看
题目点这里

题解:

这道题题意不是很好理解。每次输入第一行给一个密码表,第二行是一个翻译了一半的密文(也可能翻译完成)。将密文再按照密码表全部翻译一遍后,结尾已经翻译过的部分会合原密文相同。从(len+1)/2处截开,然后拿原文KMP比较,最后匹配成功的位数就是已经翻译好的位数,对应输出就好了。实现稍微有点复杂。

代码实现:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#define MAX 100010

using namespace std;

int T;
int len;
int pos;
char A[MAX];
char B[MAX];
int Next[MAX];
char Table[30];
char cypher[MAX];
char alpha[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
map<char,int> mm;
void pre();
void kmp();
void getnext();
void Transfer();
void print(int t);
int main()
{
scanf("%d",&T);
getchar();
while( T-- ){
gets(Table);
gets(cypher);
pre();
len = strlen(cypher);
strcpy(B,cypher+(len+1)/2);
strcpy(A,cypher);
Transfer();
kmp();
print(pos);
}
return 0;
}

void pre(){
for( int i = 0; i < 26; i++ ){
mm[Table[i]] = i;
}
return ;
}
void print(int t){
printf("%s",cypher);
for( int i = pos; i < len-pos; i++ ){
printf("%c",A[i]);
}
printf("\n");
}

void kmp(){
int i =0,j = 0;
getnext();
int tmp = strlen(B);
for( i = 0; i < tmp; i++ ){
while( j > 0 && B[i] != A[j] ){
j = Next[j];
}
if( B[i] == A[j] ){
j++;
}
}
pos = j;
}

void getnext(){
int i = 0, j = -1;
Next[0] = -1;
Next[1] = 0;
int ll = strlen(A);
while( i < ll ){
if( j == -1 || A[j] == A[i] ){
Next[++i] = ++j;
}
else{
j = Next[j];
}
}
return ;
}

void Transfer(){
for( int i = 0; i < len; i++ ){
A[i] = alpha[mm[cypher[i]]];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  kmp