https://pintia.cn/problem-sets/994805260223102976/problems/994805272659214336
这题太坑了,真的太坑了。我想出了几种不合法的情况。以字符串的形式输入每个数字,遍历字符串的每一个字符,
1、 对于每一个数字,只有负号、小数点和数字这三种情况。只要不是这三种之一,就不合法。
2、如果该字符是负号,
则必须在第一位,否则不合法;
则长度不能是一位,否则不合法;
4、如果该字符是小数点,
如果小数点前没有数字,则不合法;
如果已经有小数点了,则不合法;
如果第一次出现小数点,标记flag;
5、如果该字符是数字,
如果小数点没有出现,统计数字个数为before;
如果小数点出现了,统计数字个数为after。
6、如果小数点后的数字超过2个,则不合法。
测试点2的错误在于,当合法数字的个数是1个时,输出的 “The average of 1 number is” 的number不是复数形式,0个或多个合法数字的才是numbers,复数形式。
测试点3的错误在于,评测系统把 123. 当做是合法的数,所以在判断after的时候,只判断它是否大于等于3,不要判断等于0。
#include<iostream>
using namespace std;
int main() {
int n, count=0, right, flag, before, after;
double sum=0, num;
char ch;
string temp;
cin >> n;
for(int i=0; i<n; i++){
cin >> temp;
right = 1;
flag = 0;
before = 0;
after = 0;
for(int j=0; j<temp.size() && right==1; j++){
// 除开这三种字符都是不合法
if(temp[j] != '-' && temp[j] != '.' && (temp[j]<'0' || temp[j]>'9'))
right = 0;
// 对于负号,如果负号不在第一位、只有一个负号,不合法
if(temp[j]=='-' && (j!=0 || temp.size()==1))
right = 0;
// 对于小数点
if(temp[j]=='.'){
if(before==0)// 如果小数点前没有数字,不合法
right = 0;
if(flag==0) // 如果是第一次出现,标记flag
flag = 1;
else if(flag==1)// 如果出现第二个小数点,不合法
right = 0;
}
// 对于数字
if(temp[j]>='0' && temp[j]<='9'){
if(flag == 0)
before ++;
else if(flag == 1)
after ++;
}
}
num = atof(temp.c_str());
if((flag == 1 && after>=3) || num < -1000 || num > 1000)
right = 0;
if(right == 1){
count ++;
sum += num;
}else{
cout << "ERROR: " << temp << " is not a legal number" << endl;
}
}
if(count == 0){
cout << "The average of 0 numbers is Undefined" << endl;
}else if(count == 1){
printf("The average of 1 number is %.02lf\n", sum);
}else{
printf("The average of %d numbers is %.02lf\n", count, sum/count);
}
return 0;
}