1054 求平均值 (20 分)

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

解题思路:
Alice: 这题麻麻赖赖的,一点都不圆润!
盘它
Bob: 如图所示,盘它!!
Alice: 你说怎么盘呐 ?
Bob: 题目只说要我们求所有合法的实数的平均值,可是没有明确说出所有非法的形式啊。只说了是个实数,在[-1000, 1000]之内,精确到小数点后两位小数。
Alice: 这样不行吗?
Bob: 这样不好,你看输入样例中有aaa这种压根儿就是不是实数的,还有2.3.4这种奇葩,万一它要是还有像++--++--1++--这种怪兽,那就只能跑了。。
Alice: 跑什么,如果所有的非法形式都在题目和案例中说明了呢?出题人哪有你想的那么坏》》
Bob: [・ヘ・?],嘿我跟你说这题还有坑呢!
Alice: 我看出来一个,合法实数只有一个的时候输出的是The average of 1 number is Y这里面是number 不是 numbers。
Bob:不错哦,还有一个我们前面的题目也遇到过。保留小数点后两位数字》》
Alice: en… o ! 截断 ! 就是会出现 - 0 的那种情况。
Bob: 对,其余应该没啥了。
Alice: 恩,输入最多才只有100个,用Python 也不会超时了。哎呀,我现在都想去学一学C++模板库了,做题目方便啊。
Bob: ヾ(。ꏿ﹏ꏿ)ノ゙


代码:

def main():
    N = int(input())
    # 接收输入的正整数N
    temp = [x for x in input().split()]
    # 用一个字符列表接收 输入的N个实数
    count = sums = 0
    for x in temp:
        # 对于输入的每个实数
        if is_legal(x):
            # 如果这个实数是合法的
            count += 1
            # count 记录输入数据中有多少个合法的实数
            sums += float(x)
            # 强制转换为浮点型后,累加求和
        else:
            # 对于输入数据中的每一个非法实数,输出
            print("ERROR: {} is not a legal number".format(x))
    if count == 0:
        # 如果一个合法的实数也没有
        print("The average of 0 numbers is Undefined")
    elif count > 1:
        # 如果有多于一个的合法实数
        average = float(sums) / count
        # 计算平均数, 为啥这里还有要float呢?其实不必用,可能是写的时候过于谨慎了。
        if abs(average) < 0.01:
            # 同样的,保留两位小数有着截断的问题。所以需要预先判断处理一下。
            average = 0
        print("The average of {} numbers is {:.2f}".format(count, average))
        # 输出平均值并保留两位小数
    elif count == 1:
        # 如果仅仅有一个合法实数
        average = float(sums) / count
        # 这个其实不必需,可能是从上面复制粘贴的,懒得改了。
        if abs(average) < 0.01:
            # 同样处理截断的问题
            average = 0
        print("The average of {} number is {:.2f}".format(count, average))
        # 为啥子 只有一个 合法实数的时候要单独拿出来呢?
        # 因为只有一个合法实数就不能使用numbers而要使用number 


def is_legal(string):
    """判断传入的字符串是否是合法的浮点数"""
    availale_chars = "0123456798.+-"
    # 一个合法浮点数的字符串中只能出现available_chars中的字符
    # 不好意思, availale 拼写错误,应为 available
    if string.count('.') > 1:
        # 如果有多于1个小数点,则为非法实数。合法实数的小数点个数应为0或者1
        return False
    for x in string:
        if not x in availale_chars:
            # 如果传入的字符串中存在不在available_chars 中的字符,即为非法实数
            return False
    num = float(string)
    """程序执行到此,传入的字符串基本上就是一个实数了。其实我也不确定是不是还有其
    他的非法形式,我想就这样试一下,如果还有,程序到这儿就会抛出异常,那就是“非零
    返回”。如果没有非零返回,说明我们已经干掉了所有连数都不是的非法形式。"""
    if num < -1000 or num > 1000:
        # 如果不满足题目中的范围,那也是一个非法实数
        return False
    if '.' in string and len(string) - 1 - string.index('.') > 2:
        # 如果小数点后由多于两个数字的,也是非法字符。实际公式为len(string) -1 - (string.index('.') + 1) + 1
        return False
    return True
    # 如果这个字符串经历了重重考验,那它就是一个合法的实数。


if __name__ == '__main__':
    main()


易错点:

  • 保留两位小数面临着截断的问题。
  • 只有一个合法实数的时候,输出中使用的是number而不是numbers
  • 合法实数的小数点个数只能是0个或者1个。

总结:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值