PTA L1-025 正整数A+B(详解)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
前言本期是关于正整数A+B的详解内容包括四大模块题目代码实现大致思路代码解读今天你c了吗
题目
题的目标很简单就是求两个正整数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
? + ? = ?
代码实现
#include<stdio.h>
#include<string.h>
int is_integer(char ptr[])
{
int len = strlen(ptr);
int ret = 0;
if (len > 4)
{
return -1;
}
else
{
int i = 0;
for (i = 0; i < len; i++)
{
if (ptr[i] >= '0' && ptr[i] <= '9')
{
ret = ret * 10 + (ptr[i] - '0');
}
else
{
return -1;
}
}
}
if (ret < 1 || ret>1000)
{
return -1;
}
else
{
return ret;
}
}
int main()
{
char arr[100] = { 0 };
char str[100] = { 0 };
scanf("%s ", arr);
gets(str);
int a = is_integer(arr);
int b = is_integer(str);
if (a == -1 && b == -1)
{
printf("? + ? = ?");
}
else if (a == -1 && b != -1)
{
printf("? + %d = ?", b);
}
else if (a != -1 && b == -1)
{
printf("%d + ? = ?", a);
}
else if (a != -1 && b != -1)
{
printf("%d + %d = %d", a, b, a + b);
}
return 0;
}
大致思路
1. 存储问题输入的可能为数字or一串字符故而我们使用字符数组存储输入的值
这样原本的数字变成了数字字符
2. 输入问题我们会输入A 空格 B,采用scanf与gets结合
不能使用scanf一次读取A和B
不能使用gets一次读取A和B
原因
题目告知我们把输入中出现的第1个空格认为是A
和B
的分隔。题目保证至少存在一个空格并且B
不是一个空字符串。
即A是可以被完整读取的B可以被完整读取or不完整读取可能存在多个空格
输入存在多个空格的情况
123 456 sask
A的内容123
B的内容456 sask
若是使用scanf一次读取A和B可能会写出如下代码
scanf("%s%s", arr, str);
调试可以看到123是完整读取的456 sask则是不完整读取的
不完整读取的会导致打印结果出错
会打印出错误结果123 + 456 = 579
而不是正确结果 123 + =
因为scanf默认遇到空格读取结束123可以被完整读取而在读取456 sask时scanf只会读走空格之前的456
若是使用gets一次读取A和B可能会写出如下代码
gets(arr);
gets(str);
调试可以看到输入的内容全部被存入了arr数组中str数组是空的
因为gets的作用是读取一串字符可以一并读取一串字符中的空格直到遇到\n或到达EOF才会停止 所以第一个gets函数就一直读取直到遇到\n
采用scanf与gets结合
scanf("%s ", arr);
gets(str);
scanf负责读取123 空格A的内容+视作A
和B
的分隔的第一个空格
gets负责读取456 sask
注意scanf一定也要把第一个空格第1个空格认为是A
和B
的分隔读走不会将空格存入arr数组中否则gets会读取第一个空格和B的内容然后存入str数组原本只存入B的内容中导致结果错误
3. 输出问题存在四种情况
情况一输出 ? + ? = ?
情况二输出 ? + %d = ?
情况三输出 %d + ? = ?
情况四输出%d + %d = %d
代码解读
part 1 判断是否为正整数的函数实现
int is_integer(char ptr[])
{
int len = strlen(ptr);
int ret = 0;
if (len > 4)
{
return -1;
}
else
{
int i = 0;
for (i = 0; i < len; i++)
{
if (ptr[i] >= '0' && ptr[i] <= '9')
{
ret = ret * 10 + (ptr[i] - '0');
}
else
{
return -1;
}
}
}
if (ret < 1 || ret>1000)
{
return -1;
}
else
{
return ret;
}
}
返回-1输入的不是正整数
返回相应的数字是正整数由数组中的数字字符转化相加构成
此函数判断若数组中所存储的一个个字符是数字字符则返回它们组成起来能构成的数字
字符转成数字字符-'0'=数字
因为一个个数字字符组合在一起能够构成的数字不会是-1题目要求正整数才是唯一正确合法的输入
1. 首先判断字符串的长度长度>4不合法因为A
和B
都在区间[1,1000]最长是4位
int len = strlen(ptr);
if (len > 4)
{
return -1;
}
2. 若是长度合法再来遍历数组中的每一个字符
else
{
int i = 0;
for (i = 0; i < len; i++)
{
if (ptr[i] >= '0' && ptr[i] <= '9')
{
ret = ret * 10 + (ptr[i] - '0');
}
else
{
return -1;
}
}
}
若是字符是数字字符则返回其能构成的数字代码如下
ret = ret * 10 + (ptr[i] - '0');
如 '1‘ '2’ '3' 所对应的就是数字123
转换前一个字符所代表的数字*10+当前字符-'0'=现在的数字
如123怎么能够由123组成呢
step1 0*10+1=1
step2 1*10+2=12
step3 12*10+3=123
ret初始化为数字0step1ret*10+1由字符1转换:'1'-'0')=1
step2: ret(存储的是step中的数字1*10+2由字符2转换=12
step3ret存储的是step2中的数字12*10+3由字符3转换=123
若是字符不是数字字符则返回-1
else
{
return -1;
}
3. 判断ret中存储的由一系列数字字符构成的数字是否在[1,1000]之间
if (ret < 1 || ret>1000)
{
return -1;
}
else
{
return ret;
}
此时ret中的数字是1~4位现在要判断的是其数值有没有小于1或者大于100
若是数值不合理则返回-1表明数值为非正整数
若是数值合理则返回数值 一定不是-1
part 2 总体框架
char arr[100] = { 0 };
char str[100] = { 0 };
scanf("%s ", arr);
gets(str);
int a = is_integer(arr);
int b = is_integer(str);
if (a == -1 && b == -1)
{
printf("? + ? = ?");
}
else if (a == -1 && b != -1)
{
printf("? + %d = ?", b);
}
else if (a != -1 && b == -1)
{
printf("%d + ? = ?", a);
}
else if (a != -1 && b != -1)
{
printf("%d + %d = %d", a, b, a + b);
}
读取A和B的内容分别存储到arr数组和str数组
a和b接收函数的返回结果
若是返回结果的值是-1不是正整数
若返回结果的值不是-1是正整数