1033 旧键盘打字问题描述

问题描述

问题分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main() {
string bad_key;
string in;
getline(cin, bad_key);
getline(cin, in);
map<char,short> bad;
bad['+'] = 0;
for (int i = 0; i < bad_key.size(); ++i) {
bad[bad_key[i]] = 1;
}
for (int i = 0; i < in.size(); ++i) {
if (bad['+'] == 1 && (in[i] >= 'A' && in[i] <= 'Z')) continue;
if (bad[in[i]] == 1 || bad[in[i] - 'A' + 'a'] == 1) continue;
cout<<in[i];
}
cout<<endl;
return 0;
}

​ 我的思路是先判断上档键是不是损坏,如果损坏就跳过所有大写字母,紧接着判断当前键是否损坏,大写字母和符号可以直接在map中找到,小写字母就转换成大写字母然后再判断。但是这种方法是有问题的,测试点4始终不通过。

​ 我看了一些其他人的博客,大部分测试点4不通过的原因是因为被题目误导把其他符号都当做上档键处理。显然我不是这一问题。

​ 最终,我发现了自己的问题所在!先来看看ASCII码表。

ASCII码

​ 所有大写字母与小写字母的ASCII码相差32,所有小写字母只需要减去32就可变成大写字母。而上面代码的判断逻辑是如果当前字符没命中,就减去32判断。假设当前判断字符L为(76),坏键为 “,”(44),那L就会被误判为逗号不输出,就会造成答案错误。

解决方法

​ 解决方法是修改判断逻辑只有小写字母才考虑-32判断,就可以解决了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main() {
string bad_key;
string in;
getline(cin, bad_key);
getline(cin, in);
map<char,short> bad;
bad['+'] = 0;
for (int i = 0; i < bad_key.size(); ++i) {
bad[bad_key[i]] = 1;
}
for (int i = 0; i < in.size(); ++i) {
if (bad['+'] == 1 & (in[i] >= 'A' && in[i] <= 'Z')) continue;
if(in[i] >='a' && in[i] <= 'z' && bad[in[i] + 'A' - 'a'] == 1) continue;
if (bad[in[i]] == 1) continue;
cout<<in[i];
}
cout<<endl;
return 0;
}