PTA 1054 求平均值 (20 分) C++实现

该博客介绍了如何编写一个C++程序,用于处理包含非法输入的实数序列并计算合法数字的平均值。程序首先定义合法输入的范围和精度,然后逐个检查输入,对非法输入输出错误信息,合法输入则累加求和。最后,根据合法输入的数量计算平均值并输出。示例代码包括了两种不同的实现方式,一种使用字符串处理,另一种使用`sscanf()`和`sprintf()`函数。
摘要由CSDN通过智能技术生成

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

解题思路:

不符合规范的数字原样输出,符合的就加入总和后求其平均数
Tips:输出规范:
The average of K numbers is Y
如果 K 为 1,则输出 The average of 1 number is Y。
这里的区别在于number是否加了s

代码示例(最后一个测试点没过,如果发现哪里出了问题,可以评论指出):

#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <string>
#include <numeric>
#include <map>
using namespace std;

bool deal(string str); //判断数字是否符合规范 符合才返回true

int flag = 0; //判断负号是否存在

int main()
{
	int n;
	cin >> n;

	vector<double> ans; //存符合规范的数

	while (n--)
	{
		string str;
		cin >> str;
		
		//该数为负数时的处理方式是不同的
		if (!(str[0] >= '0' && str[0] <= '9')) //如果第一个字符不是数字
		{
			if (str[0] == '-')
			{
				flag = 1;
				string temp = "";
				for (int i = 1; i < str.length(); i++)
				{
					temp += str[i];
				}

				if (deal(temp))
				{
					string temp_plus = "-" + temp;
					ans.push_back(stof(temp_plus)); //将字符串转换为数字
				}
			}
			else
			{
				cout << "ERROR: " << str << " is not a legal number" << endl;
			}
		}
		else
		{
			flag = 0;
			if (deal(str))
			{
				ans.push_back(stof(str));
			}
		}
	}

	if (ans.size() == 0)
	{
		cout << "The average of 0 numbers is Undefined" << endl;
	}
	else if (ans.size() == 1)
	{
		cout << "The average of 1 number is ";
		printf("%.2f\n", ans[0]);
	}
	else
	{
		/*for (int i = 0; i < ans.size(); i++)
		{
			cout << ans[i] << " ";
		}
		cout << endl;*/

		cout << "The average of " << ans.size() << " numbers is ";
		double sum = accumulate(ans.begin(), ans.end(), 0.000); //利用范围求和函数accumulate来求和

		printf("%.2f\n", sum / ans.size());
	}
}

bool deal(string str)
{
	int cnt_point = 0; //数有几个小数点
	int index = 0; //获取小数点位置的下标
	for (int i = 0; i < str.length(); i++)
	{
		if (!(str[i] >= '0' && str[i] <= '9'))
		{
			if (str[i] == '.')
			{
				index = i;
				cnt_point++;
			}
			else
			{
				if (flag == 1)
				{
					cout << "ERROR: -" << str << " is not a legal number" << endl;
					flag = 0;
				}
				else
				{
					cout << "ERROR: " << str << " is not a legal number" << endl;
				}

				return false;
			}
		}
	}
	if (cnt_point >= 2)
	{
		if (flag == 1)
		{
			cout << "ERROR: -" << str << " is not a legal number" << endl;
			flag = 0;
		}
		else
		{
			cout << "ERROR: " << str << " is not a legal number" << endl;
		}
		return false;
	}
	else if (cnt_point == 0)
	{
		if (stof(str) > 1000)
		{
			if (flag == 1)
			{
				cout << "ERROR: -" << str << " is not a legal number" << endl;
				flag = 0;
			}
			else
			{
				cout << "ERROR: " << str << " is not a legal number" << endl;
			}
			return false;
		}
	}
	else
	{
		int cnt_point_nums = 0; //数小数点后的数有多少个
		for (int j = index + 1; j < str.length(); j++)
		{
			if (!(str[j] >= '0' && str[j] <= '9'))
			{
				if (flag == 1)
				{
					cout << "ERROR: -" << str << " is not a legal number" << endl;
					flag = 0;
				}
				else
				{
					cout << "ERROR: " << str << " is not a legal number" << endl;
				}
				return false;
				/*break*/
			}
			else
			{
				cnt_point_nums++;
			}
		}

		if (cnt_point_nums > 2)
		{
			if (flag == 1)
			{
				cout << "ERROR: -" << str << " is not a legal number" << endl;
				flag = 0;
			}
			else
			{
				cout << "ERROR: " << str << " is not a legal number" << endl;
			}
			return false;
		}
	}

	return true;
}

运行结果:

在这里插入图片描述

AC代码(没看懂):

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
/* 必看:
sscanf() : 从一个字符串中读进与指定格式相符的数据
sprintf() : 字符串格式化命令,主要功能是把格式化的数据写入某个字符串中 
*/

int main() {
    int n, cnt = 0;
    char a[50], b[50];
    double temp, sum = 0.0;
    cin >> n;
    for(int i = 0; i < n; i++) {
        scanf("%s", a);
        sscanf(a, "%lf", &temp);
        sprintf(b, "%.2f",temp);
        int flag = 0;
        for(int j = 0; j < strlen(a); j++)
            if(a[j] != b[j]) flag = 1;
        if(flag || temp < -1000 || temp > 1000) {
            printf("ERROR: %s is not a legal number\n", a);
            continue;
        } else {
            sum += temp;
            cnt++;
        }
    }
    if(cnt == 1)
        printf("The average of 1 number is %.2f", sum);
    else if(cnt > 1)
        printf("The average of %d numbers is %.2f", cnt, sum / cnt);
    else
        printf("The average of 0 numbers is Undefined");
    return 0;
}

再次运行:

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crazy.宥思

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值