本题的基本要求非常简单:给定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

解体思路:

吐槽:
题目对 007000.01 这种数据居然都是接受的....
题目对 12. 这种数据也是接受的...
.9 也是接受的,不过测试点未包含这样的数据(本文的代码一不接受,代码二接受)
像这种对输出格式要求很高的题目,应该描述得更加清晰才是。

题目的格式控制说得很“宽泛”,实际上只有以下 3 点:

  • 除了符号外,只能包含数字和小数点;
  • 小数点只能有一位;
  • 小数点后最多有两位。

本文包含两种解法:
代码一未使用 atof 函数,手动实现了类似功能。
代码二使用了 atof 函数。

代码一:

概述:
首先,字符串有效长度大于 8 的舍去(最大为 -1000.00 这种情况)。然后将符号(正负)单独录入。之后就只剩下数字和小数点,非这两种类型的字符可以直接 Pass 掉,退出循环,输出当前字符串。输入的过程中注意控制小数点的个数,然后进行字符串转 double 型的处理

具体细节:
使用字符串来录入数据。题目中没有给定字符串长度,这里直接设定为 1000,如果提交不过,更改也很方便。

首先判断第一位是否是 '+' 或者 '-',若是,指针指向下一位(j=1)。如果为负,则置 flag_negative 为 -1,最后 sum 值乘以它就转换成了负数。

然后开始录入剩余的数字:

  • 非数字和小数点,标记为无效,然后退出。
  • 如果满足条件,开始转换字符串。这里使用的方法是,比如 123.45,先将 thisnum 计算至 12345,最后再除以 100 (由 dot 来统计),就可以得到其真正值。
  • 再注意小数点的情况。如果之前未遇到数字或者有两个小数点,则标记为无效。(之前一开始就把类似 21. 这种小数点在末尾的数字当作无效数据,导致测试点 4 一直通不过。)
  • 最后指针走到字符串末尾时,对 sum 和 count 进行统计。

代码二:

使用了 ctype.h 中的 isdigit 函数判断是否为数字字符,使用了 atof 函数将字符串转为 double 型数值。

atof 函数省去了转换为数值的部分,只要先筛选出来既符合 atof 函数格式又是有效字符的格式就可以。先了解一下 atof 函数的参数格式:

该函数包含在 <stdlib.h> 中。

它可以将一个字符串转换为双精度的浮点数。

输入一串具有特殊类型的字符串可以被解释为一个数值。该函数在遇到第一个无法作为数的一部分的字符时停止。这个字符也可能是字符串结束符。

其参数格式为:

[whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
  • whitespace 可以是空格,可以是 Tab。
  • sign 可以是 '+' 或者 '-'。
  • digits 是一个或多个十进制字符。
  • 如果小数点前没有出现数字,那么在小数点之后至少要有一个数字。
  • 十进制数字中也可以包含一个指数,由一个引导字符 (d, D, e 或者 E) 加上一个可选的十进制数字构成。

atof 函数更加宽容,比如输入 12.34ab,它会一直转换到自己不能转换的位置,所以它会输出 12.34

根据题目的要求,在对字符串转换前做出以下筛选即可:

  • 除了符号外,只能包含数字和小数点;
  • 小数点只能有一位;
  • 小数点后最多有两位。

解体代码:

代码一:

    #include<stdio.h> #include<string.h>#define MAX 1000int IsNumber (int i);int main() {    int N;scanf("%d", &N);double sum = 0;int count = 0;for (int i=0; i<N; i++) {char s[MAX];scanf("%s", &s);int flag_negative = 1, invalid = 0;int len = strlen(s), j = 0;if (len <= 8) {if (s[0] == '-' || s[0] == '+') {if (s[0] == '-') flag_negative = -1;if (s[0] == '+') flag_negative = 1;j = 1;if (len == 1) {invalid = 1;} // 只有一个负号或正号的情况 } int dot_count = 0; // 小数点个数 int thisnum = 0;int dot = 1; // 用 1 10 100 这样的数来记录小数位数 int flag = 0; // 标记遇到数字 for (j; j<len; j++) {if (!IsNumber(s[j]) && s[j]!='.') {invalid = 1;break;} // 非数字 & 小数点,就退出 if (IsNumber(s[j]) && dot_count<2) {thisnum = thisnum * 10 + s[j] - '0';if (dot_count) {dot *= 10;if (dot == 1000) {invalid = 1;break;} // 小数点后有 3 位为无效 }flag = 1;}if (s[j] == '.') {dot_count ++;if (!flag || dot_count==2) {invalid = 1;break;} // 之前没遇到数字/小数点有两个}  if (j == len-1) {  double temp = (double)thisnum / (dot * flag_negative);if (temp<=1000 && temp>=-1000) {    count ++; sum += temp;} else {invalid = 1;}}}           if (invalid) {printf("ERROR: %s is not a legal number\n", s);} } else {printf("ERROR: %s is not a legal number\n", s);}}if (count) {if (count == 1) {printf("The average of 1 number is %.2f\n", sum/count);         } else {printf("The average of %d numbers is %.2f\n", count, sum/count);}} else {printf("The average of 0 numbers is Undefined\n");}return 0;} int IsNumber (int i) {if (i>='0' && i<='9') {return 1;} else {return 0;}} 

代码二:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX 1000int IsValid (char *s);int main()
{    int N;scanf("%d", &N);double sum = 0;int count_valid = 0;for (int i=0; i<N; i++) {char s[MAX];scanf("%s", &s);if (IsValid(s)) {double temp = atof(s);if (temp>=-1000 && temp<=1000) {sum += temp;count_valid ++;} else {printf("ERROR: %s is not a legal number\n", s);}} else {printf("ERROR: %s is not a legal number\n", s);}}if (count_valid) {if (count_valid == 1) {printf("The average of 1 number is %.2f\n", sum/count_valid);           } else {printf("The average of %d numbers is %.2f\n", count_valid, sum/count_valid);}} else {printf("The average of 0 numbers is Undefined\n");}   return 0;
} int IsValid (char *s) {int len = strlen(s); // 不要把 strlen 放在循环里,耗时(虽然不影响本题) int count_dot = 0; int after_dot = 0; // 统计小数点之后的数字 if (len <= 8) {for (int j=0; j<len; j++) {if ((s[j]=='+' || s[j]=='-') && j==0) {continue;} // 跳过正负号 if (!isdigit(s[j]) && s[j]!='.') {return 0;} // 非数字和小数点,返回 0 if (count_dot) {after_dot ++;if (after_dot == 3) {return 0;} // 小数点后有 3 位,返回 0 } if (s[j]=='.') {count_dot ++; if (count_dot == 2) {return 0;} // 小数点等于 2 个时,返回 0 } }return 1;} else {return 0;}
}

转载于:https://www.cnblogs.com/andywenzhi/p/5848616.html

1054. 求平均值相关推荐

  1. 1054. 求平均值 (20)

    1054. 求平均值 (20)本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是[-1000,1000]区间内的实数, ...

  2. 【Python】1054 求平均值(Python异常处理练习)

    1. 题目 2. 代码 重坑,读题不仔细,导致耗时多. 题目中合法数字当只用一个的时候,输出的结果中的是number,而不是numbers # https://pintia.cn/problem-se ...

  3. PTA 1054 求平均值 (c++ 代码+分析)

    1054 求平均值 (20 分) 分析:这个题乍一看并不难,但是丢分的点还是挺多的. 1.要注意只有一个小数点 2.小数点不能放在首位,而且首位是负号的话不能只有这一位. 3.每位只能是数字,且小数点 ...

  4. 【最优解法】1054 求平均值 (20分)_31行代码AC

    立志用更少的代码做更高效的表达 Pat乙级最优化代码+题解+分析汇总-->传送门 本题的基本要求非常简单:给定 N 个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个" ...

  5. 1054 求平均值(PAT乙级 C++)

    题目 本题的基本要求非常简单:给定 N 个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是 [−1000,1000] 区间内的实数,并且最多精确到小 ...

  6. PAT 乙级 1054. 求平均值 (20) Java版

    本题的基本要求非常简单:给定N个实数,计算它们的平均值.但复杂的是有些输入数据可能是非法的.一个"合法"的输入是[-1000,1000]区间内的实数,并且最多精确到小数点后2位.当 ...

  7. 【PAT乙级】1054 求平均值 (20 分)

    题目地址 测试点 2:k==1 number没有s 测试点 3:12. 这种是合法的 #include<cstdio> #include<iostream> #include& ...

  8. PTA 1054 求平均值 (20 分)

    文章目录 code1 18分 code2 20分 注意点 code1 18分 #include<iostream> #include<string.h> using names ...

  9. 12-1054. 求平均值

    1054. 求平均值 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题的基本要求非常简单:给定N个实 ...

最新文章

  1. 关于sybase数据库的锁
  2. 大数据系列文章-Hadoop的HDFS读写流程(二)
  3. oracle11g迁移到12cpdb,12c跨平台完成PDB的备份迁移
  4. C语言使用array实现stack(附完整源码)
  5. chrome使用技巧
  6. yum配置中driver-class-name: com.mysql.jdbc.Driver报错
  7. 1月31日 资源网站(素材模板)
  8. 随想录(程序员的缺点)
  9. Mybatis-Pagehelper
  10. PANIC: Could not open: AVD
  11. JavaScript对象创建对象的四种方式
  12. 牛顿法、梯度下降法原理及Python编程应用
  13. Python(二十五):排序、反转
  14. rbw数字信号处理_基于FPGA的数字中频信号处理的设计与实现
  15. html5音乐播放器格式midi,html5音频标签是否非正式地包含.mid(MIDI)?
  16. 单片机控制光耦开关继而控制电机转动
  17. app抓包于appium爬取数据
  18. 前端:基于Vue框架以及Axios实现天气预报系统
  19. 「NFT 之王」无聊猿与品牌的跨界营销!
  20. 流量池是什么?有什么作用?

热门文章

  1. java8 内部类_Java8基础知识(五)内部类
  2. 开源 java CMS - FreeCMS2.8 数据对象 site
  3. Linux时间子系统(十六) clockevent
  4. nRF5 SDK for Mesh(四) 源码编译
  5. Linux下用dump实现备份和还原
  6. Spark入门(Python版)
  7. 如何预估服务器带宽需求【转】
  8. 会计基础第二次模拟题(3)
  9. 第2章 算法1---《大话数据结构》读书笔记
  10. 关于SQLServer2005的学习笔记——SQL查询解析步骤