哎呀,又是看似简单的A+B模型,这题确实也是A+B,不过这个题让我debug1个多小时才找出来问题所在,服了,真是所谓细节决定成败,这题也挺值得记录下来的,话不多嗦,看题
题的目标很简单,就是求两个正整数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:
? + ? = ?
其他正常的我不说,对于这题最恶心的地方总结一下并给出解决方法
有些特殊案例过不了也就是在这个地方!!
对于数据的输入,这里一定一定要看清A和B的区别!!A可以为空字符串!第一个空格后面都是B!
因此我们在输入时应该注意假如A为空字符串的情况,此时用cin呀scanf呀都不好读入,因为cin会跳过前面的空格直到读到字符,如图
因此我在网上找那些先cin在getchar()吸收空格在getline这种说法,无法解决这个A为空串时的问题。最好的方法应该是直接当一行大字符串读入然后去找第一个空格,把前面的截掉就是A,后面的就都算B,这样最简单,因为可以判断这个大字符串假如第一个就是空格,那A就是空字符串,这样就解决了判断A是否为空字符串的问题
这里只给让我debug最久的一个步骤,剩下对于大字符串具体的操作处理方法这里给出详细代码
代码如下:
#include<iostream>
#include<string>
using namespace std;
bool a_ifsuit = true, b_ifsuit = true;//这里设置两个布尔数组判断a和b是否满足题意需要保留下来
int sum1, sum2;//设置a和b为数字时表示的值int main()
{string S;//由于a可以为空字符串,我们直接输入一行来处理getline(cin, S);//处理S的过程for (int i = 0; i < S.size(); i++) {//从前往后遍历找a,到第一个空格停止if (S[i] == ' ') {//找到a的位置之后,就是对a的判断以及转化if (i == 0) a_ifsuit = false;int base = 1;for (int j = i - 1; j >= 0; j--) {//假如找到不是代表数字的字符直接退出循环if (S[j] < '0' || S[j]>'9') {a_ifsuit = false;break;}//否则把每个数字从后往前迭代加起来,相当于个位十位百位等等一个一个加,不同位数乘以不同的base值else {sum1 += base * (S[j]-'0');base *= 10;}}//判断加起来的数是否在题给的区间if (sum1 > 1000 || sum1 <= 0) a_ifsuit = false;//此时空格后面的就都是b了,这里和上面一样判断b假如都是数字就转化bbase = 1;//由于b也是从个位开始计算和因此这里把base值设回1for (int j = S.size() - 1; j > i; j--) {if (S[j] < '0' || S[j]>'9') {b_ifsuit = false;break;}else {sum2 += base * (S[j] - '0');base *= 10;}}if (sum2 > 1000 || sum2 <= 0) b_ifsuit = false;//最后通过a和b是否保留下来数字进行输出if (a_ifsuit && b_ifsuit) cout << sum1 << " + " << sum2 << " = " << sum1 + sum2;else if (a_ifsuit && !b_ifsuit) cout << sum1 << " + ? = ?";else if (!a_ifsuit && b_ifsuit) cout << "? + " << sum2 << " = ?";else cout << "? + ? = ?";break;}}return 0;
}