PTA L1-025 整数A+B

PTA L1-025 整数A+B

题目描述

题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000]。稍微有点麻烦的是,输入并不保证是两个正整数。

输入格式:
输入在一行给出A和B,其间以空格分开。问题是A和B不一定是满足要求的正整数,有时候可能是超出范围的数字、负数、带小数点的实数、甚至是一堆乱码。

注意:我们把输入中出现的第1个空格认为是A和B的分隔。题目保证至少存在一个空格,并且B不是一个空字符串。

输出格式:
如果输入的确是两个正整数,则按格式A + B = 和输出。如果某个输入不合要求,则在相应位置输出?,显然此时和也是?。

输入样例1:
123 456
输出样例1:
123 + 456 = 579

输入样例2:
22. 18
输出样例2:
? + 18 = ?

输入样例3:
-100 blabla bla…33
输出样例3:
? + ? = ?

AC代码如下:

#include
#include
using namespace std;
int main()
{
	char a[1005], b[1005], c;
	char* p = a, * q = b;
	int flag_a = 0, flag_b = 0, sum_a = 0, sum_b = 0;
	scanf("%s", a);//第一部分
	c = getchar();//吸收空格
	scanf("%[^\n]", b);//读取一个字符集
	//遍历两个集合,若不符合正整数形式,flag置为1
	for (; *p != '\0'; p++)
		if (*p < 48 || *p>57) {
			flag_a = 1;
			break;
		}
	p = a;//指针复位
	for (; *q != '\0'; q++)
		if (*q < 48 || *q>57) {
			flag_b = 1;
			break;
		}
	q = b;
	//若为正整数,则计算A,B的数值
	if (!flag_a) {
		while (*p != '\0') {
			sum_a *= 10;
			sum_a += (int)(*p - '0');
			p++;
		}
	}
	if (!flag_b) {
		while (*q != '\0') {
			sum_b *= 10;
			sum_b += (int)(*q - '0');
			q++;
		}
	}
	//按照格式输出
	if (sum_a > 1000 || sum_a < 1) {
		if (sum_b > 1000 || sum_b < 1) {
			printf("? + ? = ?");
			return 0;
		}
		else
		{
			printf("? + %s = ?", b);
			return 0;
		}
	}
	else
	{
		if (sum_b > 1000 || sum_b < 1) {
			printf("%s + ? = ?", a);
			return 0;
		}
		else
		{
			printf("%s + %s = %d", a, b, sum_a + sum_b);
			return 0;
		}
	}
}

思路

  • 通过字符数组存储字符串
    • 关于空格的处理
      • 第一个空格作为A,B分隔符,可通过scanf("%s")处理掉,再用getchar吸收空格
      • 之后的空格作为B的组成部分则需要全部读取知道换行符出现,此处有多种处理方式
        • 1)使用scanf读取字符集scanf("%[^\n]")
        • 2)使用gets读取
        但是PTA的编译器似乎没有gets,也没有gets_s
        
    • 另外还可以用getline来读取一行,然后从中找到第一个空格所在处作为A,B的分隔。
  • 判断求和前提
    • 遍历两个数组,判断是否为正整数形式
    • 使用flag_a;flag_b来存储判断结果
  • 在判定求和的条件下,通过将A,B中每位数按权相加得到两者的数值
    • 判断数值是否在[1,1000]内
    • 按标准正确标准错误输出结果

代码分析

  • 通过flag_,flag_b判断是否求和
    • 不求和则sum_a/sum_b为零,在代码向后执行时跳转到对应输出
    • 求和则按权重相加,数字位数每向左一位,权重变为原来的10倍。在下边的代码中将判断和的范围,即 A,B的值。
  • 按要求输出。

个人感想

这道题一下做了60分钟,做的过程中思路挺明确,只是在采用哪种判断依据(只用flag还是和sum一起)的时候重构一下代码出了很多逻辑错误,耗费一点时间,大头都用在了对字符串的处理上,比如scanf停止后,空格仍然留在缓冲区,需要getchar 吸收掉,此前一直以为空格被删除掉了;各种从stdin读取数据的函数的运行模式不是很清楚;读取字符串的多种方式。

参考文章

送上大神关于I/O的总结一份
sun_top的深入详解标准C语IO

错误之处敬请指正

你可能感兴趣的:(ACM,c语言,算法,acm竞赛)