【欢迎关注微信公众号:计算机黑科学大全,对话框回复:PAT乙级真题】获取全部真题详解及代码示例
个人博客地址:https://mzwang.top
旧键盘打字
题目描述:
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键,打出的结果文字会是怎样?
输入格式:
输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过 1 0 5 10^5 105 个字符的串。可用的字符包括字母 [
a
-z
,A
-Z
]、数字0
-9
、以及下划线_
(代表空格)、,
、.
、-
、+
(代表上档键)。题目保证第 2 行输入的文字串非空。
注意:如果上档键坏掉了,那么大写的英文字母无法被打出。输出格式:
在一行中输出能够被打出的结果文字。如果没有一个字符能被打出,则输出空行。
输入样例:
7+IE. 7_This_is_a_test.
输出样例:
_hs_s_a_tst
题目来源:PAT乙级1033
作者:CHEN, Yue
单位:浙江大学
下面的代码1与代码2大同小异。代码1没有’‘充分’‘运用散列,其只把大小写字母和数字’‘充分’'进行散列,其它几个字符进行了单独处理,充分利用了空间,代码不简洁。代码2进行了完全散列,因为这些字符的ASCII码不会超过128,故将字符散列数组开到128,这样就简化了代码,这种方式更优。
定义字符散列数组str_hash[],初始化为0,读入第一行字符串,对每一个字符(坏掉的键)c,将str_hash[c]置为1;读入第二行字符串,对该字符串的每一个字符,先检查其是否能输出,若相应的键已坏掉,则跳过输出,进行下一次判断。
题目保证第 2 行输入的文字串非空,但没保证第1行输入的文字串非空,因此若第1行输入为空时要有相应的处理,否则将导致测试点2不通过。若第1行文字串的输入用如下形式:
scanf("%s",str);
则当第1行为空时,由于%s不能读入回车,其会跳过第1行直接将第2行的内容读入str[]。此处我们可采用如下方式来读入,这样第1行为空时也不会影响到下一行,当然还有很多其它方式。
for(int i = 0; (c = getchar()) != '\n'; i++){
str[i] = c;
}
小提示:请将以下代码保存为.cpp
格式(C++程序)左右滑动代码以查看完整代码
代码1
//此法没有'充分'利用散列,但节省空间
#include
#define MAXLEN 100001
using namespace std;
int main()
{
int str_hash[41] = {
0};//字符散列,标记该字符对应的键是否坏掉,
//可用字符最多67个,大小写英文字母不区分剩41个
char str[67];
char c;
for(int i = 0; (c = getchar()) != '\n'; i++){
//此处不要用%s直接读入字符串,%s不能读入回车,第一行为空时不能读入,从而导致str[]错误读入第二行
str[i] = c;
}
for(int i = 0; str[i] != '\0'; i++){
//标记坏掉的键
int temp;
if(str[i] >= '0'&&str[i] <= '9'){
//数字
temp = str[i] - '0';//数字字符转换为数值
}
else if(str[i] >= 'a'&&str[i] <= 'z'){
//小写字母
temp = str[i] - 'a' + 10;//小写字母转换为数值
}
else if(str[i] >= 'A'&&str[i] <= 'Z'){
//大写字母
temp = str[i] - 'A' + 10;//大写字母转换为数值
}
else if(str[i] == '_'){
temp = 36;
}
else if(str[i] == ','){
temp = 37;
}
else if(str[i] == '.'){
temp = 38;
}
else if(str[i] == '-'){
temp = 39;
}
else if(str[i] == '+'){
temp = 40;
}
str_hash[temp] = 1;
}
char str1[MAXLEN];
scanf("%s",str1);
for(int i = 0; str1[i] != '\0'; i++){
if(str1[i] >= 'A'&&str1[i] <= 'Z'){
if(str_hash[40]||str_hash[str1[i] - 'A' + 10]){
//若上挡键坏了或该大写字母键坏了
continue;
}
}
else if(str1[i] >= 'a'&&str1[i] <= 'z'){
if(str_hash[str1[i] - 'a' + 10]){
//若小写字母键坏了
continue;
}
}
else if(str1[i] >= '0'&&str1[i] <= '9'){
if(str_hash[str1[i] - '0']){
//数字键坏了
continue;
}
}
else if(str1[i] == '_'&&str_hash[36]){
continue;
}
else if(str1[i] == ','&&str_hash[37]){
continue;
}
else if(str1[i] == '.'&&str_hash[38]){
continue;
}
else if(str1[i] == '-'&&str_hash[39]){
continue;
}
printf("%c",str1[i]);
}
printf("\n");
return 0;
}
代码2
//'充分'利用散列,代码较简洁
#include
#define MAXLEN 100001
using namespace std;
int main()
{
int str_hash[128] = {
0};//这些字符的ASCII码值不会超过128
char str[67];//可用字符最多67个
char c;
for(int i = 0; (c = getchar()) != '\n'; i++){
str[i] = c;
}
for(int i = 0; str[i] != '\0'; i++){
//标记坏掉的键
str_hash[str[i]] = 1;
}
char str1[MAXLEN];
scanf("%s",str1);
for(int i = 0; str1[i] != '\0'; i++){
if(str_hash['+'] == 1){
//下档键已坏
if(str1[i] >= 'A'&&str1[i] <= 'Z'){
//大写字母不输出
continue;
}
}
if(str1[i] >= 'A'&&str1[i] <= 'Z'){
//大写字母
if(str_hash[str1[i] + 32] == 1){
//对应小写字母已坏
continue;//大写字母不输出
}
}
if(str1[i] >= 'a'&&str1[i] <= 'z'){
//小写字母
if(str_hash[str1[i] - 32] == 1){
//对应大写字母已坏
continue;//小写字母不输出
}
}
if(str_hash[str1[i]] == 1){
continue;
}
printf("%c",str1[i]);
}
printf("\n");
return 0;
}