解题思路:
解这类需要构建字母映射的加密/解密问题,核心在于正确且无冲突地构建映射表,并利用该表进行解码。
注意事项:
这个问题所描述的加密规则是这样的:
1.字母映射:每个字母仅对应另一个唯一的字母,即加密和解密所用的替换表,每个大写字母从 'A' 到 'Z' 都映射到另一个特定的字母(可能是自己)。
2.无二义性:不同的原文字符不能映射到相同的加密字符,并且每个加密字符有且仅有一个原文字符对应。
3.唯一性:每个字母的映射是唯一的,不允许出现多个字母映射到同一个字母。
举例说明:
输入:
AB
CD
DCBA
这里提供了两个字符串的映射:
A -> C
B -> D
根据这个规则,解码 DCBA:
D -> B
C -> A
B -> ? (无法映射,因为 B 在原文中没有相应的加密对)
A -> ? (无法映射,因为 A 在原文中没有相应的加密对)
在这种情况,程序会打印 Failed 因为不是所有字母都有对应关系。
这套规则确保了加密和解密过程的可靠性和唯一性,避免了二义性和冲突。
参考代码:
#include<stdio.h>
#include<string.h>//字符串头文件
int main()
{
char arr1[101];//密文
char arr2[101];//明文
char arr3[101];//加密的消息,需要翻译为明文
char arr4[26]={0};//定义并初始化数组来存储字母到其密字的映射关系。26个英文字母
char arr5[26]={0};//定义并初始化数组来判断某个字母是否已经被映射为密字,也是26大小
scanf("%s %s %s",arr1,arr2,arr3);//输入翻译规则—密文和明文,拿到的密文消息
//将字符型转换为整型
int len1=strlen(arr1);//密文
int len2=strlen(arr2);//明文
int len3=strlen(arr3);//消息
//循环遍历,构建映射表
for(int i=0;i<len1;i++)//密文
{
int arr6=arr1[i]-'A';//arr6是当前加密字符在arr4数组中的索引(序号)
int arr7=arr2[i]-'A';//当前原始字符在arr2数组中的索引(序号)
//判断,通过arr4数组将加密字符映射到原始字符
//第一种情况
//(1)还没有设置加密字符
if(arr4[arr6]==0)//如果加密字符还未被设置
{
if(arr5[arr7])//原文为真,表示该原始字符已经被用在密字
{
printf("Failed\n");//存在冲突,输出Failed
return 0;
}
arr4[arr6]=arr2[i];//将原始字符赋给加密字符
arr5[arr7]=1;//设置原始字符arr5[arr7]为真
}
//(2)原文字符没有对应的密文字符
else if(arr4[arr6]!=arr2[i])//如果加密字符arr4[arr6]不为零且不等于原始字符arr2[i]
{
printf("Failed\n");//存在冲突,输出Failed
return 0;
}
}
//检查完整性
//第二种情况
//遍历arr4数组(密文),检查是否所有字母都有对应的密字
for(int i=0;i<26;i++)
{
if(arr4[i]==0)//如果arr4(密文)数组存在未被设置,表示有些字母没有出现在原消息中
{
printf("Failed\n");//输出“Failed”并退出程序
return 0;
}
}
//翻译信息
//循环遍历arr3数组
for(int i=0;i<len3;i++)
{
//通过arr4数组将每个加密字符映射到相应的原始字符并输出
int arr6=arr3[i]-'A';//当前消息在arr6(密文)数组中索引(序号)
printf("%c",arr4[arr6]);//输出对应消息的密文
}
printf("\n"); //最后输出一个新行
return 0;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复