团体程序设计天梯赛-练习集 L1-011 A-B (20 分) 双指针法解决

本题要求你计算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;
}

以上仅是我个人拙见,希望能对你有所帮助。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Huaperion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值