目录
1,题目描述
Sample Input 1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
Sample Output 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
Sample Input 2:
2
aaa -9999
Sample Output 2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
题目大意
将合法的数字进行求和,并输出平均值。
注意
1,不合法的数据:
- 字符串中含除“- ,.,数字”以外的字符;
- 若含负号,但未出现在第一位;
- 含有超过一个小数点的数据;
- 小数点后面位数超过2位的数据;
- 表示范围超过区间[-1000, 1000];
2,sscanf与sprintf:
- double x;
- char s[100], ss[100];
- scanf("%s", s);
- sscanf(s, "%lf", &x); //将这一字符串输出为一个浮点数x中
- sprintf(ss, "%.2f", x); //将这一浮点数输出为一个有两位小数的字符串ss中
- for(int i = 0; s[i] != '\0'; i++) //注意以字符数组表示字符串末尾的方法
3,stod:
- string s = "123.2";
- double x = stod(s);
4,输出:
2,思路
- 设计函数判断字符串是否为合法数字,并将合法数据存放至全局变量x中:
- 接收数据并判断,累加合法数据:
- 输出:
3,AC代码
#include<bits/stdc++.h>
using namespace std;
double x;
char s[100], ss[100];
bool isNum(){
sscanf(s, "%lf", &x); //将这一字符串输出为一个浮点数x中
sprintf(ss, "%.2f", x); //将这一浮点数输出为一个有两位小数的字符串ss中
for(int i = 0; s[i] != '\0'; i++) //注意以字符数组表示字符串末尾的方法
if(s[i] != ss[i]) return false;
if(abs(x) > 1000) return false;
return true;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int N;
scanf("%d", &N);
double ans = 0;
int num = 0;
for(int i = 0; i < N; i++){
scanf("%s", s);
if(isNum()){
num++;
ans += x;
}else{
printf("ERROR: %s is not a legal number\n", s);
}
}
if(num == 0)
printf("The average of 0 numbers is Undefined");
else if(num == 1)
printf("The average of 1 number is %.2f", ans);//number不加s
else
printf("The average of %d numbers is %.2f", num, ans / num);
return 0;
}
4,解题过程
第一搏
自认为这是涉及数字字符串处理中,最简单的一题。(毕竟不是哪种毫无思路,怎么做都别扭的题目orz,但。我错了)
#include<bits/stdc++.h>
using namespace std;
bool isNum(string s){
int point = 0;
int i = s[0] == '-' ? 1 : 0;
for(; i < s.size(); i++){
if(s[i] == '.'){
if(point == 0)//目前没有小数点
point = i;
else//已有小数点
return false;
}else if(!isdigit(s[i]))//是否含有非数字字符
return false;
}
if(s.size() - point - 1 > 2)//判断精确位置是否超过2位
return false;
double n = stod(s);
if(n >= -1000 && n <= 1000)
return true;
return false;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int N;
scanf("%d", &N);
string s;
double ans = 0;
int num = 0;
for(int i = 0; i < N; i++){
cin>>s;
if(isNum(s)){
num++;
ans += stod(s);
}else{
cout<<"ERROR: "<<s<<" is not a legal number"<<endl;
}
}
if(num == 0)
printf("The average of 0 numbers is Undefined");
else if(num == 1)
printf("The average of 1 number is %.2f", ans);//number不加s
else
printf("The average of %d numbers is %.2f", num, ans / num);
return 0;
}
第二搏
又到了精彩的推理环节了o(* ̄▽ ̄*)ブ
在判断字符串是否为数字时,考虑了四种情况:
- 含有多个小数点;
- 含有非数字字符;
- 精确位数大于2;
- 数字表示范围超过[-1000,1000];
此时,若s=='.'或s=='-.'或s=='-'时,stod函数会出错,于是加上了这个:
可惜并不是
第三搏
又发现,point的初始值不能设为0,因为若输入为 .0.12时,第二个小数点读入时检测到point为0,便将第二个小数点的位置覆盖掉point。于是我便把point初值设为-1:
然而仍然不是。。。
第四搏
此时的我已经在击碎电脑屏幕的边缘(╯‵□′)╯︵┻━┻
(虽然已经了解到,使用sscanf可以完全不用考虑这些问题,但浪费了我一个小时的BUG,我绝不会这么轻易的放过他!(╯▔皿▔)╯)
。
事实证明,我的倔强将会再次浪费我两个小时。。。
经过即为曲折的过程(寻找类似代码,手动设计测试数据,甚至查验stod函数的特性。。。)
终于( ̄y▽ ̄)╭ Ohohoho.....
按照我的算法,当字符串中未出现小数点时,point将保持初值-1,若此时不判断point是否为-1,而直接利用s.size() - point - 1 > 2来判断小数点后的位数时,会产生精度位数过大的错误。
比如输入123,此时point = -1,小数点后的位数3-(-1)=4,误判为超过精度!
第五搏
当我把求索过程中的补丁去掉以后(如图红框的部分)
仍然可以通过全部示例,说明.12是否合法并不影响题目的解决!(看网上说法不一,经过亲身实践后,确实没有此差异,可能没有涉及到类似的示例)
#include<bits/stdc++.h>
using namespace std;
bool isNum(string s){
int point = -1;
string s1 = s.substr(0, 2);
if(s == "-." || s == "." || s == "-" || s1 == "-." || s1[0] == '.')
return false;
int i = s[0] == '-' ? 1 : 0;
for(; i < s.size(); i++){
if(s[i] == '.'){
if(point == -1)
point = i;
else
return false;//小数点超过一个
}else if(!isdigit(s[i]))//是否含有非数字字符
return false;
}
if(point != -1 && s.size() - point - 1 > 2)//判断精确位置是否超过2位
return false;
double n = stod(s);
if(n >= -1000 && n <= 1000)
return true;
return false;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int N;
scanf("%d", &N);
string s;
double ans = 0;
int num = 0;
for(int i = 0; i < N; i++){
cin>>s;
if(isNum(s)){
num++;
ans += stod(s);
}else{
cout<<"ERROR: "<<s<<" is not a legal number"<<endl;
}
}
if(num == 0)
printf("The average of 0 numbers is Undefined");
else if(num == 1)
printf("The average of 1 number is %.2f", ans);//number不加s
else
printf("The average of %d numbers is %.2f", num, ans / num);
return 0;
}