傳送門
https://pintia.cn/problem-sets/994805260223102976/problems/994805272659214336
題目
本題的基本要求非常簡單:給定N個實數(shù),計算它們的平均值。但復(fù)雜的是有些輸入數(shù)據(jù)可能是非法的。一個“合法”的輸入是[-1000,1000]區(qū)間內(nèi)的實數(shù),并且最多精確到小數(shù)點(diǎn)后2位。當(dāng)你計算平均值的時候,不能把那些非法的數(shù)據(jù)算在內(nèi)。
輸入格式:
輸入第一行給出正整數(shù)N(<=100)。隨后一行給出N個正整數(shù),數(shù)字間以一個空格分隔。
輸出格式:
對每個非法輸入,在一行中輸出“ERROR: X is not a legal number”,其中X是輸入。最后在一行中輸出結(jié)果:“The average of K numbers is Y”,其中K是合法輸入的個數(shù),Y是它們的平均值,精確到小數(shù)點(diǎn)后2位。如果平均值無法計算,則用“Undefined”替換Y。如果K為1,則輸出“The average of 1 number is Y”。
輸入樣例1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
輸出樣例1:
ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38
輸入樣例2:
2
aaa -9999
輸出樣例2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
分析
最初的分析是:
1.先判長度,太長直接out;
2.如果長度符合,開始遍歷,計算小數(shù)點(diǎn)的數(shù)目,如果超過1,即非法;而一旦發(fā)現(xiàn)有非數(shù)字非小數(shù)點(diǎn)的情況,也認(rèn)定為非法;
3.到這步后肯定是只有數(shù)字和小數(shù)點(diǎn)還有負(fù)號的組合了,再排除小數(shù)點(diǎn)后面超過兩位的情況(用長度-小數(shù)點(diǎn)的索引看是否大于3),還有去掉正數(shù)情況下小數(shù)點(diǎn)開頭的情況,以及負(fù)數(shù)情況下小數(shù)點(diǎn)在第2個位置(索引為1)的情況。接著還有以小數(shù)點(diǎn)結(jié)尾的情況,也要考慮進(jìn)去。(這一條也是這道題不嚴(yán)謹(jǐn)?shù)牡胤?,如果認(rèn)定了小數(shù)點(diǎn)結(jié)尾的情況為非法,則第四個測試點(diǎn)無法通過,去掉即可通過)
后來怕出現(xiàn)000000.1這種情況,于是把對長度的判斷去掉了,但是這道題中的4個測試點(diǎn)并沒有這種數(shù)據(jù)。
遇到的坑:
1.stringstream轉(zhuǎn)換時,要進(jìn)行清空和重置狀態(tài)標(biāo)志的操作(保險起見兩個都做);
stringstream.clear(); //重置stringstream的狀態(tài)標(biāo)志
stringstream.str(""); //清空數(shù)據(jù)
2.不知道是不是坑,還是改掉了,就是開始是拿double型變量>=1000比較的,但是怕double和int的相等比較出問題,所以還是只比較double型變量<1000比較保險一些;
3.原題中有說明,當(dāng)k=1時輸出number而不是numbers。
源代碼
//C/C++實現(xiàn)
#include <iostream>
#include <sstream>
using namespace std;
int main(){
int n;
scanf("%d", &n);
string tmp;
double tmp_d;
int tmp_i;
stringstream ss;
int correctCount = 0;
double sum = 0;
for(int i = 0; i < n; ++i){
cin >> tmp;
bool correct = true;
bool minus = false;
if(tmp[0] == '-'){
minus = true;
}
int count = 0; //計算小數(shù)點(diǎn)的個數(shù)
int j = (minus == false ? 0 : 1);
for(; j < tmp.size(); ++j){
if(tmp[j] == '.'){
++count;
if(count > 1){ //小數(shù)點(diǎn)個數(shù)超過1
correct = false;
break;
}
}
else if(tmp[j] >= '0' && tmp[j] <= '9'){
continue;
}
else{ //非小數(shù)點(diǎn)非數(shù)字
correct = false;
break;
}
}
if(!correct){
cout << "ERROR: " << tmp << " is not a legal number" << endl;
}
else{
if(count == 0){ //整數(shù)
ss << tmp;
ss >> tmp_i;
ss.clear(); //重置stringstream的狀態(tài)標(biāo)志
ss.str(""); //清空數(shù)據(jù)
if(tmp_i < -1000 || tmp_i > 1000){
correct = false;
}
else{
sum += tmp_i;
++correctCount;
}
}
else{ //小數(shù)
int point = tmp.find('.');
if(tmp.size() - point > 3){ //小數(shù)點(diǎn)后面超過2位
correct = false;
}
//else if(point == tmp.size() - 1){ //小數(shù)點(diǎn)在最后一位,也不對
// correct = false;
//}
else if(minus == true && point == 1){ //形如:-.x
correct = false;
}
else if(minus == false && point == 0){ //形如:.x
correct = false;
}
else{
ss << tmp;
ss >> tmp_d;
ss.clear(); //重置stringstream的狀態(tài)標(biāo)志
ss.str(""); //清空數(shù)據(jù)
if(tmp_d < -1000 || tmp_d > 1000){
correct = false;
}
else{
sum += tmp_d;
++correctCount;
}
}
}
if(!correct){
cout << "ERROR: " << tmp << " is not a legal number" << endl;
}
}
}
if(correctCount == 0){
printf("The average of 0 numbers is Undefined\n");
}
else if(correctCount == 1){
printf("The average of 1 number is %.2f\n", sum);
}
else{
printf("The average of %d numbers is %.2f\n", correctCount, sum / correctCount);
}
return 0;
}