我刷PAT - 1108 Finding Average (20 分)

题目介绍

The basic task is simple: given N real numbers, you are supposed to calculate their average. But what makes it complicated is that some of the input numbers might not be legal. A legal input is a real number in [−1000,1000] and is accurate up to no more than 2 decimal places. When you calculate the average, those illegal numbers must not be counted in.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then N numbers are given in the next line, separated by one space.

Output Specification:

For each illegal input number, print in a line ERROR: X is not a legal number where X is the input. Then finally print in a line the result: The average of K numbers is Y where K is the number of legal inputs and Y is their average, accurate to 2 decimal places. In case the average cannot be calculated, output Undefined instead of Y. In case K is only 1, output The average of 1 number is Y instead.

Sample Input 1:

7
5 -3.2 aaa 9999 2.3.4 7.123 2.35

Sample Output 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

Sample Input 2:

2
aaa -9999

Sample Output 2:

ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined

注解

原本我的解法,就是根据题目的输入样例,来归纳一个合格的浮点数是怎么样的。

我当时总结出了这样的规律:

  1. 如果有符号,那就在开头,否则就不要有
  2. 数字中间部分,只能有一次浮点数,或者不要有,而只有数字
  3. 不能出现除符号+数字+浮点之外其余字符
  4. 在[-1000,1000]范围内
  5. 浮点数只有精确两位

然后写出了很繁琐的代码,不过最后倒也能过。

但翻看了柳婼学姐的代码:1108. Finding Average (20)-PAT甲级真题_柳婼 の blog-CSDN博客

不得不赞叹,柳婼学姐在这题的思路确实厉害。

如果不是有这个函数,原本给定一个字符串,来判断它是不是一个正常的浮点数是非常麻烦的。

但现在有了sscanf和sprintf的存在,这个大难题就交给了系统,是内置函数帮我们做的。

(正常读进去了就接着后面的判断,如果是错误输入而无法读取,那么temp就会保持原本的值,起初是0,不影响,之后就算读入了,也是旧值,后面字符串逐位判断也是走不过的)

随后,得到的是一个正常浮点数。

再判断范围,以及通过输出到字符串与此前状态比较来判断是否是不超过两位小数

题目也就结束了。

代码

我的很繁琐但也能过的代码,权当记录一下。

#include<bits/stdc++.h>
using namespace std;

//要求
//1.如果有符号,那就在开头,否则就不要有
//2.数字中间部分,只能有一次浮点数,或者不要有,而只有数字
//3.不能出现除符号+数字+浮点之外其余字符
//4.在[-1000,1000]范围内
//5.浮点数只有精确两位 

//最后一个测试点不太好想,59.也是合理的浮点数!

int main()
{
	int N;
	cin>>N;
	
	string s;
	double sum=0;
	int K=0;
	while(N--)
	{
		cin>>s;
		
		//先判断是不是要求的数-符号部分 
		int flag=1;		//是的标记
		if(!(s[0]=='-' || isdigit(s[0])))	flag = 0;
		
		int cou=0;		//浮点出现次数 
		for(int i=1;i<s.size();i++)
		{
			if(!(isdigit(s[i]) || s[i]=='.'))
			{
				flag=0;
				break;
			}
			
			if(s[i]=='.')	cou++;
		}
		 
		if(cou>1)	flag=0;
		
		
		if(flag==0)	//不是合理数字 
		{
			cout<<"ERROR: "<<s<<" is not a legal number\n";
			continue;
		}
		
		//判断是不是要求的数-数值部分  <=> 转换计算 
		int point = s.find(".");		//小数点位置 
		if(point==-1)		//整数
		{
			int value = 0;
			if(s[0]=='-')
			{
				for(int i=1;i<s.size();i++)	value = value*10+s[i]-'0';
				value = -value;
			}
			else
			{
				for(int i=0;i<s.size();i++)	value = value*10+s[i]-'0';
			}
			
			if(value>=-1000&&value<=1000)
			{
				sum += value;
				K++;
			}
			else
				cout<<"ERROR: "<<s<<" is not a legal number\n";
		}
		else			//浮点数 
		{
			if(s[0]=='-' && s.size()-point-1<=2 || s[0]!='-'&&s.size()-point-1<=2)
			{
				double value = 0;
				
				if(s[0]=='-')
				{
					for(int i=1;i<point;i++)	value = value*10+s[i]-'0';
					if(s.size()-point-1==1)	value += 0.1*(s[point+1]-'0');
					else if(s.size()-point-1==2) value += 0.1*(s[point+1]-'0')+0.01*(s[point+2]-'0');
					value = -value;
				}
				else
				{
					for(int i=0;i<point;i++)	value = value*10+s[i]-'0';
					if(s.size()-point-1==1)	value += 0.1*(s[point+1]-'0');
					else if(s.size()-point-1==2)	value += 0.1*(s[point+1]-'0')+0.01*(s[point+2]-'0');
				}
				
				if(value>=-1000&&value<=1000)
				{
					sum += value;
					K++;
				}
				else
					cout<<"ERROR: "<<s<<" is not a legal number\n";
			}
			else
				cout<<"ERROR: "<<s<<" is not a legal number\n";	
		}				
	}
	
	if(K==0)		printf("The average of 0 numbers is Undefined\n");
	else if(K==1)	printf("The average of 1 number is %.2lf\n",sum);
	else			printf("The average of %d numbers is %.2lf\n",K,sum/K);
	
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值