原题如下:
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:
? + ? = ?
不妨我再给这道题多几个输入输出样例
输入样例4:
22 22 22输出样例4:
22 + ? = ?输入样例5:
1 1234输出样例5:
1 + ? = ?输入样例6:
0 123输出样例6:
? + 123 = ?
通过上述几个笔者增加的输入输出样例,估计得不了满分的同学应该知道需要考虑些什么边界条件了吧。 题目中要求我们注意:我们把输入中出现的第1个空格认为是A和B的分隔。也就是说B中的空格数可无法保证。
有了这些理解,笔者首先写出了如下代码:
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
char a[1000],b[1000];
cin>>a;
getchar();
gets(b);
int A,B,i,len1,len2,temp1=0,temp2=0,num[1000];
len1=strlen(a);
len2=strlen(b);
for(i=0; i<len1; i++)
{
if(a[i]-48>=0&&a[i]-48<=9)
{
temp1++;
}
}
for(i=0; i<len2; i++)
{
if(b[i]-48>=0&&b[i]-48<=9)
{
temp2++;
}
}
A=temp1==len1;
B=temp2==len2;
if(A&&B)
{
int C=atoi(a)>=1&&atoi(a)<=1000;
int D=atoi(b)>=1&&atoi(b)<=1000;
if(C&&D)
cout<<a<<" + "<<b<<" = "<<atoi(a)+atoi(b)<<endl;
else if(C&&!D)
cout<<a<<" + "<<"? = ?"<<endl;
else if(!C&&D)
cout<<"? + "<<b<<" = ?"<<endl;
else
cout<<"? + ? = ?"<<endl;
}
else if(A&&!B)
{
cout<<a<<" + "<<"? ="<<" ?"<<endl;
}
else if(!A&&B)
cout<<"? "<<"+ "<<b<<" = ?"<<endl;
else
cout<<"? + ? = ?"<<endl;
}
#include "bits/stdc++.h"
using namespace std;
int main()
{
char a[99999],b[99999],atemp[99999],btemp[99999];
scanf("%s",a);
getchar();
gets(b);
sscanf(a,"%[0-9]",atemp);
sscanf(b,"%[0-9]",btemp);
if(strlen(a)>strlen(atemp)&&strlen(b)>strlen(btemp)||!(atoi(a)>=1&&atoi(a)<=1000)&&!(atoi(b)>=1&&atoi(b)<=1000))
{
cout<<"? + ? = ?"<<endl;
}
else if(strlen(a)>strlen(atemp)||!(atoi(a)>=1&&atoi(a)<=1000))
{
cout<<"? + "<<b<<" = ?"<<endl;
}
else if(strlen(b)>strlen(btemp)||!(atoi(b)>=1&&atoi(b)<=1000))
{
cout<<a<<" + ?"<<" = ?"<<endl;
}
else
{
cout<<a<<" + "<<b<<" = "<<atoi(a)+atoi(b)<<endl;
}
}
顿时压缩到了30行以内思路显得十分清晰,对于这道题,我们要判断的,首先是是a和b是不是个 非负整数,也就是a和b中除了0-9这些数字是否存在其他字符,若有,直接pass掉这个数,若没有,则这个数已经是非负整数,由题意我们又知道a和b必须保证在[1,1000]内,故需要进行二重判断,理论上2*2=4种情况,笔者就分了4中情况;
附:关于sscanf()这个函数的用法,做如下解释:
sscanf() - 从一个字符串中读进与指定格式相符的数据.
函数原型:
int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
int scanf( const char *format [,argument]... );
说明:
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 | L}]type | ' ' | '\t' | '\n' | 非%符号}
注:
1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
3、width表示读取宽度。
4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
5、type :这就很多了,就是%s,%d之类。
6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值
支持集合操作:
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性
注意:在读入的字符串是空字符串时,sscanf函数并不改变待读入到的字符串的值。
例子:
1. 常见用法。
char buf[512] = ;
sscanf("123456 ", "%s", buf);
printf("%s\n", buf);
结果为:123456
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf("123456 ", "%4s", buf);
printf("%s\n", buf);
结果为:1234
3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
sscanf("123456 abcdedf", "%[^ ]", buf);
printf("%s\n", buf);
结果为:123456
4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
printf("%s\n", buf);
结果为:123456abcdedf
6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
结果为:12DDWDFF
7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
sscanf(“hello, world”, "%*s%s", buf);
printf("%s\n", buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了