本题的基本要求非常简单:给定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.借鉴网上的思路,先将字符串输入,再转换成double,最后再转换成字符串。如果两字符串最后相等,代表该字符串格式正确,再判断范围即可。
网上借鉴的思路代码:
#include<iostream>
#include <string.h>
#include <cstdio>
using namespace std;
int main()
{
int n;
double sum=0; //总和
int count =0; //合法数量
int i,j;
cin>>n;
for(i=0;i<n;i++)
{
char temp[50],_temp[50]; //temp--原始字符串 _temp--转换后字符串
double num_temp; //转换后数字
scanf("%s",temp);
sscanf(temp,"%lf",&num_temp); //将字符串temp以double形式输入num_temp中
sprintf(_temp,"%.2lf",num_temp); //将double变量num_temp 以.2lf的形式输入_temp中
int flag=1;
for(j=0;j<strlen(temp);j++) //如果temp与_temp相等
{ //temp=111,_temp=111.00 所以 以temp的长度为准
if(temp[j] != _temp[j])
{flag = 0;break;}
}
if(flag && num_temp>=-1000 && num_temp<=1000) //相等且在范围内
{count++;sum+=num_temp;}
else //否则不合法
printf("ERROR: %s is not a legal number\n", temp);
}
//输出
if(count == 0)
cout<<"The average of 0 numbers is Undefined";
else if(count == 1)
printf("The average of 1 number is %.2lf",sum);
else
printf("The average of %d numbers is %.2lf",count,sum/count);
return 0;
}
自己的代码:(可以说写得很烂)
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
double stringToDouble( string a)
{
istringstream iss(a);
double temp;
iss>>temp;
return temp;
}
bool find_p (string a,int &n) //判断小数点是否存在,并改变n来输出小数点位数
{
int i;
int sign=0;
for( i=0;i<a.size();i++)
if(a[i] == '.')
{n=i;return true; }
return false;
}
bool check( string a )
{
int p_pos=0 ; // 小数点位置
int sign = 0; // 标记此字符串是否符合规则
int i;
int t=0; //如果为正数 t=0,如果为负数,t=1
if(a[0] == '-') t=1;
if (a.size() > 7+t) {sign =1;} /*如果位数超过7位*/
else if(find_p(a,p_pos)) /*如果有小数点,p_pos为小数点位数*/
{
if(a.size()-1 - p_pos > 2) {sign = 1;} //如果小数位数大于2
else if(p_pos > 4+t) {sign = 1;} //如果小数点前位数大于4
else if(p_pos == 4+t) //如果小数点位数恰好为4
{
if(a[0+t]!='1' || a[1+t]!='0' || a[2+t]!='0' || a[3+t]!='0') //如果前四位数不是1000
{sign = 1;}
else if(a.size() - p_pos==2 && a[p_pos+1]!='0') //如果只有一位小数且不为0
{sign = 1;}
else if(a.size() - p_pos==3 && (a[p_pos+1]!='0' || a[p_pos+2]!='0') ) //如果有两位小数且任一位不为0
{sign = 1;}
}
}
else if(!find_p(a,p_pos)) /*如果没有小数位*/
{
if(a.size()>4+t) //长度大于4
{ sign = 1;}
else if (a.size() == 4+t ) //长度等于4
{
if(a[0+t]!='1' || a[1+t]!='0' || a[2+t]!='0' || a[3+t]!='0')
sign = 1;
}
else //长度小于4
{
for(i=0+t;i<a.size();i++)
if(a[i]<'0' || a[i]>'9')
{sign = 1;break;}
}
}
if(sign) /*不符合规则*/
return false;
else /*符合规则*/
return true;
}
int main()
{
int n;
cin>>n;
int count=0;
double sum=0;
for(int i=0;i<n;i++)
{
string temp;
cin>>temp;
if(!check(temp))
cout<<"ERROR: "<<temp<<" is not a legal number"<<endl;
else
{
double d_temp;
d_temp = stringToDouble(temp);
sum += d_temp;
count++;
}
}
if(count>1)
printf("The average of %d numbers is %.2lf",count,sum/count);
else if(count==1)
printf("The average of 1 number is %.2lf",sum/count);
else
printf("The average of 0 numbers is Undefined");
cout<<endl;
return 0;
}