PAT乙级 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

思路:

有两种思路:
1.第一种思路就是按照字符串判定的方法,通过重重判定(具体怎么判定写到注释里了),判断这个数是否合法。这个方法会非常麻烦,而且有时自己会给自己制造麻烦,比如我第一次做这个题的时候,甚至考虑到了前置0的问题,实际上测试数据里应该没有前置0的情况。
2.第二种方法是,不管这个数是不是合法,直接用scanf("%lf",&a)读取,再sprintf(xx,"%.2f",a)输出到字符串,比较最原始的字符串和重新输出后的字符串,是否存相等。当然这种方法可能存在原始字符串长度小于重新输出字符串长度的情况,如 输入是 5 ,重新输出是 5.00 ,虽然字符串不完全相等,但是5是一个合法输入,具体操作看代码即可。

统计数据:

PAT乙级 1054 求平均值 (20分)_第1张图片

题解 方法一:

#include 
#include 
#include 
#include 
using namespace std;

int n,cnt=0;
char num[100000];
double summ=0,tmpa;

int main(){
     
    scanf("%d",&n);
    for(int i=0;i<n;i++){
     
        scanf("%s",num);
        int dot=0,dotpos=1e7,is_ok=1,simb=0,simbpos=1e7;
        for(int j=0;j<strlen(num);j++){
       //各种判断条件
            if(!isdigit(num[j]) && num[j]!='.' && num[j]!='+' && num[j]!='-')
                is_ok=0; //出现了 . + - 以外的符号,则判定为否
            if(num[j]=='.')
                dot++,dotpos=j; //记录小数点的数量和位置
            if(num[j]=='+' || num[j]=='-')
                simb++,simbpos=j;//记录符号的位置和数量
        } //小数点多于一个,符号多于一个,小数点在首位,小数点后超过两位,判定为否
        if(simb>1 || dot>1 || dotpos==0 || dotpos<(int)strlen(num)-3) is_ok=0;
        sscanf(num,"%lf",&tmpa);
        if(simb==1 && simbpos!=0) is_ok=0; //符号不在首位,判定为否
        if(tmpa<-1000 || tmpa>1000) is_ok=0; //绝对值大于1000,判定为否
        if(!is_ok) printf("ERROR: %s is not a legal number\n",num);
        if(is_ok) summ+=tmpa,cnt++;
    }
    if(cnt>0)
        printf("The average of %d number%s is %.2f",cnt,cnt==1?"":"s",summ/cnt);
    else
        printf("The average of 0 numbers is Undefined"); //注意number和numbers
    return 0;
}

题解 方法二:

#include 
using namespace std;

int n,cnt,is_ok;
double a,summ;
char st1[1000],st2[1000];

int main(){
     
    scanf("%d",&n);
    for(int i=0;i<n;++i){
     
        scanf("%s",st1);
        sscanf(st1,"%lf",&a);
        sprintf(st2,"%.2f",a);
        is_ok=1;
        for(int i=0;i<strlen(st1) && is_ok;++i)
            if(st1[i]!=st2[i])  //这里一定是i
                is_ok=0;
        if(is_ok && a<=1000.0 && a>=-1000.0)
            ++cnt,summ+=a; //逗号表达式,这里可以把逗号理解成分号
        else
            printf("ERROR: %s is not a legal number\n",st1);
    }
    if(cnt)
        printf("The average of %d number%s is %.2f",cnt,cnt>1?"s":"",summ/cnt);
    else  //超过一个合法数字要把number写成复数形式,PAT惯用伎俩。
        printf("The average of 0 numbers is Undefined");
    return 0;
}

你可能感兴趣的:(PAT乙级,字符串,数据结构,算法,c++)