解题思路:
本题有多个限制条件需要提前判断,如下所示:
1.所有信息扫描完毕,‘A’—‘Z’所有26个字母在原信息中均出现过并获得了相应的“密字”。
2.所有信息扫描完毕,但发现存在某个(或某些)字母在原信息中没有出现。
3.扫描中发现掌握的信息里有明显的自相矛盾或错误(违反S过密码的编码规则)。
首先需要判断给定的第一个数组中‘A’~‘Z’是否都出现过,然后再判断arr1与arr2对应字符的对应关系是否唯一,若对应关系不为1或未包含所有字符,便输出Failed,若以上关系均满足,则再进行翻译工作即可,将arr3对应的元素置换为arr2中对应的元素。
注意事项:
参考代码:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
char arr1[100] = { 0 };
char arr2[100] = { 0 };
char arr3[100] = { 0 };
//定义一个数组来存储‘A’~‘Z’中字母出现的次数,将‘A’~‘Z’字母出现的次数分别存储在arr4[ 0 ]~arr4[ 25 ]中,然后遍历arr4数组中是否存在为0的元素,即可判断26个大写字母是否都出现过。
int arr4[26] = { 0 };
scanf("%s %s %s", arr1, arr2, arr3);
int len1 = strlen(arr1);
int ret = 1;
int i = 0;
int j = 0;
for (i = 0; i < len1; i++)
{
//arr4数组对应的字母出现次数加一
arr4[arr1[i] - 'A']++;
for (j = 0; j < len1; j++)
{
if (arr1[i] == arr1[j])
{
//对应关系不唯一的时候跳出循环,此时j的值不为len1,后续判断会用到
if (arr2[i] != arr2[j])
{
break;
}
}
}
//j的值不为len1时,说明上一个循环提前跳出,存在对应关系不为1的情况,i的循环也跳出,不再需要往下进行
if (j != len1)
{
ret = 0;
break;
}
}
//判断所有字母是否都出现过
int k = 0;
for (k = 0; k < 26; k++)
{
if (arr4[k] == 0)
{
break;
}
}
if (k != 26)
{
ret = 0;
}
else
{
//i的值为len1时,说明对应关系唯一,且所有字母都出现过,可以对加密数组arr3进行解密
if (i == len1)
{
int len3 = strlen(arr3);
//在arr1数组中寻找对应的元素,并用该元素在arr2中的值替换其在arr3中的值,即为解密之后的字符
//也可以构造一个字典数组,将‘A’~‘Z’字母分别对应的字符存储在其中,该部分便可以直接使用,可以有效降低复杂度
for (i = 0; i < len3; i++)
{
for (j = 0; j < len1; j++)
{
if (arr3[i] == arr1[j])
{
arr3[i] = arr2[j];
break;
}
}
if (j == len1)
{
ret = 0;
break;
}
}
if (i == len3)
{
printf("%s\n", arr3);
}
}
}
//ret = 0说明在解密之前数组存在一定的问题,则无法进行解密
if (ret == 0)
{
printf("Failed\n");
}
return 0;
}
0.0分
2 人评分