本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。
输入格式:
输入在2行中先后给出字符串A和B。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出A−B的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
问题一:scanf函数输入时出现问题
在这里,应当指出的是,scanf() 期待输入的格式与您给出的 %s 和 %d 相同,这意味着您必须提供有效的输入,比如 "string integer",如果您提供的是 "string string" 或 "integer integer",它会被认为是错误的输入。另外,在读取字符串时,只要遇到一个空格,scanf() 就会停止读取,所以 "this is test" 对 scanf() 来说是三个字符串。
显然在题目中,我们并不知道究竟有多少个空格分割,就算知道也不能用,太过麻烦。
所以就要用到另一种格式控制符%[],输入一个字符集
scanf("%[^\n]%*c",A);
scanf("%[^\n]%*c",B);
这样就可以完成输入工作。
具体的可以参考另一篇文章:scanf中的%[^\n]%*c格式
问题二:如何删除字符呢? 双指针法
利用一个指针p留在原地,指针q向前移动检索是否为B中的字符,如果不是,说明这个字符需要保留,将这个字符返回给指针p,p向前移动,q同时也向前移动,继续检索,如果是B中的字符,不用管,p在向前移动是会将其改变为有效字符,就相当与删去了这个字符。
这是我做的一个动画演示 (其实用了leetcode上的图[狗头]):
问题三:在对字符串使用双指针法调整后,我们可以发现需要的有效字符已经被放在了前面,但是我们该如何控制输出,使它刚好输出有效字符串呢?
我们可以在每次完成在A中检索B中某元素后使用newlenA记录新的A的长度,这样一方面优化了双指针使其不用重复赋值,其次在B中元素被全部检索完成后newlenA便是最终的有效长度,然后利用for循环逐个输出字符即可。
注:最后呢实际也就是一些细节的把握,比如
1.每次检索需要把双指针归位到0。
2.利用string.h中的strlen函数计算A和B的长度,便于循环次数控制。
正确代码如下:
#include<stdio.h>
#include<string.h>
int main()
{
char A[10000],B[10000];
scanf("%[^\n]%*c",A); //这里需要注意不能直接用%s的格式,因为输入的字符串中有空格
scanf("%[^\n]%*c",B); //scanf遇到空格会认为输入结束 ,这里就需要用的另一种格式符
int lenA=strlen(A),lenB=strlen(B); //利用函数确定字符串长度,以便确定循环次数
int i,p,q,newlenA=lenA; //定义双指针p,q newlenA用来保存有效字符长度 ,便于输出
for(i=0;i<lenB;i++) //双循环遍历每一个元素
{
p=0,q=0; //双指针每次检索初值均为0 ,从头检索
for(q=0;q<newlenA;q++) //每次只需要检索到有效长度就可,有效长度外的是被舍弃的字符
{
if(A[q]!=B[i])
{
A[p]=A[q]; //q在前面检索,遇到不等于B中对应元素的返回给p
p++;
}
}
newlenA=p; //更新最新长度
}
for(i=0;i<newlenA;i++) //利用有效长度输出需要的删除后的字符
{
printf("%c",A[i]);
}
return 0;
}
以上仅是我个人拙见,希望能对你有所帮助。