PAT刷题之乙级1033 旧键盘打字

PAT刷题之乙级1033(cpp)

题目描述

       旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键,打出的结果文字会是怎样?

输入格式

       输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过 10​5​个字符的串。可用的字符包括字母 [a-z, A-Z]、数字 0-9、以及下划线_(代表空格)、,.-+(代表上档键)。题目保证第 2 行输入的文字串非空
       注意:如果上档键坏掉了,那么大写的英文字母无法被打出。

输出格式

       在一行中输出能够被打出的结果文字。如果没有一个字符能被打出,则输出空行。

输入样例

7+IE.
7_This_is_a_test.

输出样例

_hs_s_a_tst

问题分析

       这题我想到了两种方法,一种是定义ASCII码值的数组,使用散列的方式来实现,一种是定义两个string字符串用来存放坏键和输入字符,然后用查找标记的方式来实现。(嘿(* ^ ▽ ^ *)嘿,我承认我想到的是第二种那个笨办法,第一种是我百度了一篇看来的)。
       现在先不说两种方法的具体细节,先讨论一下这个题目的几个关键要点。
       ① 要注意在有+和没有+时,英文字符的处理方式是不同的
       ② 第一行输入,也即坏键有可能是没有的,如果没有注意这点2号测试点会报错的
       ③如果字符全都坏了的话,要输出回车
       接下来我们来讨论讨论上面说的两种方法:
第一种: 定义一个int数组,大小为130(根据题目里定义的字符,这么大就够用了),然后根据读入坏键的ASCII码值作为索引,将该索引的数组元素值设为1。如果输入的坏键里有+,那需要将所有大写字母全部设为1,如果输入的坏键里没有+,只需要将字母坏键的大小写设为1即可。然后将输入字符中对应的数组值不是1的输出即可
第二种: 定义一个坏键字符串str1和一个输入字符串str2,如果str1里有+,那么需要将str2中全部大写字符改为星号(或者其他题目定义中未出现过的字符),如果str1里没有+,就无需特殊处理。
       那么处理手法来了(以下坏键默认无+):
       1、如果坏键字符串中有字母,那么将该字母的大小写全部改为某个标记
       2、如果坏键字符串中有数字或者其他字符,那么将该字符改为某个标记
(偷偷说一句,实践证明第一种要比第二种效率高不少,特别是在数量比较大的时候,我太菜了┭┮﹏┭┮

代码实现

核心代码如下:


第一种:

#include<stdio.h>
#include<string.h>
int main()
{
    int key[178]={0};//储存坏键
    int i,check=0;//check核对是否有输出
    char ch;
    while((ch=getchar())!='\n')
    {
        if(ch>='A'&&ch<='Z')key[ch-'A'+'a']=1;//字母大小写都存入
        key[ch]=1;
    }
    if(key['+'])for(i='A';i<='Z';i++)key[i]=1;//上档键坏掉,则所有大写无法打出
    while((ch=getchar())!='\n')
    {
        if(key[ch])continue;
        printf("%c",ch);
        check=1;
    }
    if(check==0)printf("\n");//如果没有输出,则输出\n
}
--------------------- 
原文:https://blog.csdn.net/gl486546/article/details/52387796 

第二种:
    string errorKey, inKey;//errorKey为存储坏键字符的字符串,inKey为存储输入字符
	char ch1;
	while ((ch1 = getchar()) != '\n')  //之所以这样输入是因为,errorKey有可能为空
		errorKey=errorKey+ch1;
	cin >> inKey;
	unsigned int length2 = inKey.length();
	unsigned int length1 = errorKey.length();
    int pos = errorKey.find('+');  //查找+位置
	int count = 0;
	for (unsigned int i = 0; i < length2; i++) { //对输入字符进行处理(还可以继续剪枝)
		char ch = inKey[i];
		if (isalpha(inKey[i])) {   //处理字母字符
			if (pos != errorKey.npos) {  //如果有+
				if (isupper(ch))   //将大写替换为*
					replacestr(ch, '*', inKey);
				else {     //将小写替换为*
					ch = toupper(ch);
					if (iserror(ch, errorKey)) {  //iserror函数为查找当前输入字符是否为坏键
						ch = tolower(ch);
						replacestr(ch, '*', inKey);
					}
				}
			}
			else {//没有+,将大小写全部替换为*
				ch = toupper(ch);
				if (iserror(ch, errorKey)) {
					replacestr(ch, '*', inKey);
					ch = tolower(ch);
					replacestr(ch, '*', inKey);
				}
			}
		}
		else { //其他字符处理
			if (iserror(ch, errorKey)) {
				replacestr(ch, '*', inKey);
			}
		}
	}

完整代码实现如下:

       第一种:代码在这里鸭:https://blog.csdn.net/gl486546/article/details/52387796
       第二种:代码在这里鸭~

运行实现

第一种:
运行实现


第二种:
运行实现

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值