作者的话:若有朋友复制代码去PAT试着运行遇到问题的:
1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了;
2.可能是注释原因,PAT有时候检测到注释会编译错误,所以可以先把注释删了,再进行提交回答;
3.可能是作者当初根据题目写出来的代码仍存在一些疏漏,而恰好当时的测试机制没那么完善,没检测出问题。后面测试机制有所更新,故出现问题,若有相关需要的可以评论区留言或私信作者,我看到的话会去再查一下疏漏之处,然后更新文章。
一、题目描述
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。
输入格式:
输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字 0-9、以及下划线 _(代表空格)组成。题目保证 2 个字符串均非空。
输出格式:
按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。
输入样例:
7_This_is_a_test
_hs_s_a_es
输出样例:
7TI
二、解题思路
读题:
输入给两行内容,分别是应该输入的文字和实际被输入的文字,从中找出哪些字符没有正常输入,将那些字符输出(字母用大写格式输出,相同字符不重复输出)。
题目保证两个字符串非空且至少有1个字符输入失败,每段文字是不超过 80 个字符的串(由字母、数字、下划线组成)。
思路:
1.定义需要的变量,并接收两行文字;
2.调用自定义的比较函数my_strcmp,对两行文字进行比对:若遇到计划字符和实际字符不一致的,且当前计划字符是小写字母,将其转换成大写字母再查一下有没有重复,确定没有重复再保存输入失败的字符到数组c中(字符不反复保存);
3.将数组c的内容全部输出。
三、具体实现
0.标准C源程序框架
#include <stdio.h>
int main()
{
return 0;
}
1.定义需要的变量,并接收两行文字;
//1.定义需要的变量,并接收两行文字;
char plan[81], real[81], c[38] = {0};//总共有37种字符,所以最坏情况c保存37个字符,加一个'\0'
char* cp = c;
int i = 0;
scanf("%s%s", plan, real);
2.调用自定义的比较函数my_strcmp,对两行文字进行比对:若遇到计划字符和实际字符不一致的,且当前计划字符是小写字母,将其转换成大写字母再查一下有没有重复,确定没有重复再保存输入失败的字符到数组c中(字符不反复保存);
//2.调用自定义的比较函数my_strcmp,对两行文字进行比对
my_strcmp(plan, real, cp);
函数的实现:
void my_strcmp(char* plan, char* real, char* cp)
{
int i = 0, j = 0 ;
int k = 0,q = 0;
while (plan[i] != '\0' || real[j] != '\0')//hello elo
{
if (plan[i] != real[j])//若遇到计划字符和实际字符不一致的
{
if (plan[i] >= 'a' && cp[i] <= 'z')//且当前计划字符是小写字母
{
plan[i] -= 32;//转换成大写字母
}
q = 0;//后面要从c[q]到c[k]遍历数组c找有没有重复,由于每次都要找一遍,所以每次都要把q置0
while (q < k)
{
if (cp[q] == plan[i])//如果有发现重复,循环提前结束,这也将导致q一定<k
break;
q++;
}
if (q == k)//说明循环正常走完,依然没找到和当前失败字符重复的
{
cp[k] = plan[i];//则将当前失败字符存储到数组c中
k++;//c[k]存了东西,为防止覆盖,k++,下一个失败字符会存储到(k++)后的c[k]中
}
i++;//不管有没有重复,当前c[i]比对完了,该检测下一个元素了
}
else//若当前计划和实际输入字符一样,则对两个数组的检测都移到下个元素
{
i++;
j++;
}
}
}
3.将数组c的内容全部输出。
//3.将数组c的内容全部输出。
while (cp[i] != '\0')
{
printf("%c", cp[i++]);
}
四、测试数据
感觉程序功能实现了测试数据基本上也就都过了,稍微注意一下对失败字符重复能否检测出来以及按要求输出字母全为大写字母的功能即可。
五、全部代码
#include <stdio.h>
void my_strcmp(char* plan, char* real, char* cp)
{
int i = 0, j = 0 ;
int k = 0,q = 0;
while (plan[i] != '\0' || real[j] != '\0')//hello elo
{
if (plan[i] != real[j])//若遇到计划字符和实际字符不一致的
{
if (plan[i] >= 'a' && cp[i] <= 'z')//且当前计划字符是小写字母
{
plan[i] -= 32;//转换成大写字母
}
q = 0;//后面要从c[q]到c[k]遍历数组c找有没有重复,由于每次都要找一遍,所以每次都要把q置0
while (q < k)
{
if (cp[q] == plan[i])//如果有发现重复,循环提前结束,这也将导致q一定<k
break;
q++;
}
if (q == k)//说明循环正常走完,依然没找到和当前失败字符重复的
{
cp[k] = plan[i];//则将当前失败字符存储到数组c中
k++;//c[k]存了东西,为防止覆盖,k++,下一个失败字符会存储到(k++)后的c[k]中
}
i++;//不管有没有重复,当前c[i]比对完了,该检测下一个元素了
}
else//若当前计划和实际输入字符一样,则对两个数组的检测都移到下个元素
{
i++;
j++;
}
}
}
int main()
{
//1.定义需要的变量,并接收两行文字;
char plan[81], real[81], c[38] = {0};//总共有37种字符,所以最坏情况c保存37个字符,加一个'\0'
char* cp = c;
int i = 0;
scanf("%s%s", plan, real);
//2.调用自定义的比较函数my_strcmp,对两行文字进行比对
my_strcmp(plan, real, cp);
//3.将数组c的内容全部输出。
while (cp[i] != '\0')
{
printf("%c", cp[i++]);
}
return 0;
}