目录
本题的基本要求非常简单:给定 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.范围在[-1000,1000]内 &&如果有小数点,小数至多两位;
其次,按照要求书写主函数,进行输出显示层面的编程;
分层解析:
1.是实数:
首先,输入的就不一定为一个数,所以输入的数据类型就应该是字符数组;循环遍历这个数组,需要判断这3点来证明输入的字符数组是否可以转化为实数:
只由数字、一个或零个负号、一个或零个小数点组成;
判断方法为,在满足以上条件下,符合以上条件的字符数总数是否等于字符数组长度;
2.范围与小数位数:
范围很好判断,在已经判断字符数组可以转化为实数之后,就可以用atof()函数来实现转化,从而判断范围;
关于包括atof()在内的所有字符串转数字的函数及其相应用法,请参考以下连接:https://blog.csdn.net/bc202205/article/details/128433151?spm=1001.2014.3001.5501;
小数位数:循环遍历数组,确定小数点的位置;通过求取小数点后有几个数组元素,就可以确定该字符数组所转化的实数是否满足小数位数的要求了;
代码部分:
函数代码实现如下:
#include <iostream>
#include <cstring>
using namespace std;
bool isnumber(char a[], int len)//判断是否为实数;
{
int counts = 0, countdots = 0, countfu = 0;
for (int i = 0; i < len; i++)
{
if (a[i] >= '0' && a[i] <= '9')
counts++;
else if (a[i] == '.')
countdots++;
else if (a[i] == '-')
countfu++;
}
return (counts + countdots + countfu == len)
&& (countdots == 0 || countdots == 1)
&& (countfu == 0 || countfu == 1) ? true : false;
}
bool isfloat(char a[], int len)
{
if (isnumber(a, len) && (atof(a) > 1000 || atof(a) < -1000))
return false;//判断是否为范围内的实数;
else//判断是否为2位小数以内的实数;
{
int pos = -1;
if (isnumber(a, len))
{
for (int i = 0; i < len; i++)
if (a[i] == '.')
pos = i;
if (pos == -1)
return true;
else
return len - pos - 1 <= 2 ? true : false;
}
else
return false;
}
}
int main()
{
int n;
cin >> n;
char a[100];
int counts = 0;
double sum = 0;
for (int i = 0; i < n; i++)
{
cin >> a;
if (isfloat(a, strlen(a)) == false)
cout << "ERROR: " << a << " is not a legal number" << endl;
else
{
counts++;
sum += atof(a);
}
}
//一定要对counts的情况根据题意分开讨论!
if (counts == 0)
cout << "The average of 0 numbers is Undefined";
else if (counts == 1)
{
cout << "The average of " << counts << " number is ";
printf("%.2f", sum / counts);//测试点3;
}
else
{
cout << "The average of " << counts << " numbers is ";
printf("%.2f", sum / counts);
}
return 0;
}
关于人为书写检测机制的技巧:
发现答案部分正确怎么办?判断条件太多,不妨在函数内自己书写检测机制。
如果用此方法,不太适合用“?:”表达式了,虽然if else语句相较于“?:”表达式,书写起来可能会比较繁琐,但是对于编程漏洞的检查起到很大帮助;
笔者写的检测机制如下:
#include <iostream>
#include <cstring>
using namespace std;
bool isnumber(char a[],int len)
{
int counts = 0, countdots = 0, countfu = 0;
for (int i = 0; i < len; i++)
{
if (a[i] >= '0' && a[i] <= '9')
counts++;
else if (a[i] == '.')
countdots++;
else if (a[i] == '-')
countfu++;
}
//监测点一;
if ((counts + countdots + countfu == len)
&& (countdots == 0 || countdots == 1)
&& (countfu == 0 || countfu == 1))
return true;
else
{
cout << "error1" << endl;
return false;
}
/*//原代码
return (counts+countdots+countfu == len)
&&(countdots==0||countdots==1)
&&(countfu==0||countfu==1) ? true : false;
*/
}
bool isfloat(char a[], int len)
{
if (isnumber(a, len) && (atof(a) > 1000 || atof(a) < -1000))
{
cout << "error2" << endl;//监测点二;
return false;//原代码只有这一句
}
else
{
int pos = -1;
if (isnumber(a, len))
{
for (int i = 0; i < len; i++)
if (a[i] == '.')
pos = i;
//监测点三;
if (pos == -1)
return true;
else
{
if (len - pos - 1 <= 2)
return true;
else
{
cout << "error3" << endl;
return false;
}
//return len - pos-1 <= 2 ? true : false;//原代码只有这一句;
}
}
else
{
cout << "error4" << endl;//监测点五;
return false;//原代码只有这一句;
}
}
}
int main()
{
int n;
cin >> n;
char a[100];
int counts = 0;
double sum = 0;
for(int i=0;i<n;i++)
{
cin >> a;
if (isfloat(a, strlen(a)) == false)
cout << "ERROR: " << a << " is not a legal number" << endl;
else
{
counts++;
sum += atof(a);
}
}
//一定要对counts的情况根据题意分开讨论!
if (counts == 0)
cout << "The average of 0 numbers is Undefined";
else if(counts==1)
{
cout << "The average of " << counts << " number is ";
printf("%.2f", sum / counts);//测试点3
}
else
{
cout << "The average of " << counts << " numbers is ";
printf("%.2f", sum / counts);
}
return 0;
}
这样,我们就在函数中建立了检测机制。当我们输入样例时,程序会自动告知我们,到底是函数判断的哪部分出现了漏洞;
比方说,我们现在将监测点三中的判断条件改为len-pos<=2,我们一起看一下会出现什么结果。
输入样例一,运行结果如下:
我们可以清楚地看到,2.35 这个数“应对未对”,原因是在error3的位置出现了错误,从而定点修改。
以上就是小编写的一点解析,有帮助的话帮忙点个赞呦~