https://pintia.cn/problem-sets/994805260223102976/problems/994805288530460672
思路
跟 旧键盘.那题类似,也是用计数法,用asc数组保存坏掉的键,再用应输出字符串去扫描。
测试点2:可能没有坏键,即输入的是空字符串,所以不能用cin或scanf("%s"),C语言就用fgets(),C++就用cin.getline或者getline;
测试点5:提前计算好strlen可以省时间,避免超时。
代码
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
int asc[129]= {0};
int flag=1;
char bad[100010],words[100010];
cin.getline(bad,100010);
cin.getline(words,100010);
int badlen=strlen(bad),wordslen=strlen(words);
//提前算好长度 避免超时
for (int i=0; i<badlen; i++) {
asc[bad[i]]=1;
if (bad[i]>='A' && bad[i]<='Z')
asc[bad[i]+'a'-'A']=1;
//如果是大写字母 则让小写字母处也=1
}
for (int i=0; i<wordslen; i++) {
if (asc[words[i]]==1) continue; //asc[i]==1说明是坏键
if (words[i]>='A' && words[i]<='Z' && asc['+']) continue;
//是大写字母且shift坏了
printf("%c",words[i]);
flag=0; //有输出则flag置0
}
if (flag)
printf("\n");
}
补充:fgets()用法
来自:http://c.biancheng.net/view/235.html
虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据,换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这个问题,就会发生内存越界,所以编程时建议使用 fgets()。
fgets() 的原型为:
# include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
注意:fgets(s, sizeof(s), stdin) 读入的字符要比 看上去的长度多1.
原因是因为它把回车符号\n也读进去了
fgets() 虽然比 gets() 安全,但安全是要付出代价的,代价就是它的使用比 gets() 要麻烦一点,有三个参数。它的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
其中:s 代表要保存到的内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream 表示从何种流中读取,可以是标准输入流 stdin,也可以是文件流,即从某个文件中读取,这个在后面讲文件的时候再详细介绍。标准输入流就是前面讲的输入缓冲区。所以如果是从键盘读取数据的话就是从输入缓冲区中读取数据,即从标准输入流 stdin 中读取数据,所以第三个参数为 stdin。
# include <stdio.h>
int main()
{
char str[20];
/*定义一个最大长度为19, 末尾是'\0'的字符数组来存储字符串*/
printf("请输入一个字符串:");
fgets(str, 7, stdin);
/*从输入流stdin即输入缓冲区中读取7个字符到字符数组str中*/
printf("%s\n", str);
return 0;
}