1054 求平均值 (20 分)
本题的基本要求非常简单:给定 N 个实数,计算它们的平均值。但复杂的是有些输入数据可能是非法的。一个“合法”的输入是 [−1000,1000] 区间内的实数,并且最多精确到小数点后 2 位。当你计算平均值的时候,不能把那些非法的数据算在内。
输入格式:
输入第一行给出正整数 N(≤100)。随后一行给出 N 个实数,数字间以一个空格分隔。
输出格式:
对每个非法输入,在一行中输出 ERROR: X is not a legal number
,其中 X
是输入。最后在一行中输出结果:The average of K numbers is Y
,其中 K
是合法输入的个数,Y
是它们的平均值,精确到小数点后 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、第一位必为数字或者负号(不能只有负号)
2、判断字符串从第二位开始的字符,只能出现数字或点,出现点时开启小数位计数,若出现第二个小数点,说明此数不合法。
3、经过上面的筛选,到这里的一定是数字,只要判断是否符合题目要求即可
#include<iostream> #include<string> #include<algorithm> #include<cmath> using namespace std; bool mydigit(char a) { return !(isdigit(a) || a == '.'); } int pd(string s) { int point = count(s.begin(),s.end(),'.'); //记录小数点 int m = 0; //记录小数位数 if (s.find('.') != string::npos) m = s.length() - s.find('.') - 1; if (!(s[0] == '-'&&s.length()>1) && !isdigit(s[0])) //第一位必为数字或者负号(不能只有负号) return 0; if (m <= 2 && abs(stof(s)) <= 1000 && find_if(s.begin()+1, s.end(), mydigit) == s.end()) //必须保证在题目范围内 return 1; return 0; } int main() { int n, count = 0; double t, sum = 0; string str; cin >> n; while (n--) { cin >> str; if (pd(str)) { count++; sum += stof(str); } else cout << "ERROR: " << str << " is not a legal number" << endl; } cout << "The average of " << count; if (count == 1) //看清题意 cout << " number is "; else cout << " numbers is "; if (count) printf("%0.2lf", (double)sum / count); else cout << "Undefined"; return 0; }