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.我原本的思路是做大量的判断,判断一个数字是否合法。

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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值