原題如下:
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被過濾了