PAT-BASIC1054——求平均值/PAT-ADVANCED1108——Finding Average

本文介绍了PAT编程考试中的两道关于求平均值的题目,分别是PAT-BASIC1054和PAT-ADVANCED1108。详细阐述了题目要求,重点讲解了如何判断字符串是否符合合法的数值格式,如排除非法字符、小数位数限制和数值范围。同时,提到了在处理特殊情况时的注意事项,如合法的“3.”。最后,分析了算法的时间复杂度和空间复杂度,并给出了C++的解题思路。
摘要由CSDN通过智能技术生成

我的PAT-BASIC代码仓

https://github.com/617076674/PAT-BASIC

我的PAT-ADVANCED代码仓

https://github.com/617076674/PAT-ADVANCED

原题链接

PAT-BASIC1054

https://pintia.cn/problem-sets/994805260223102976/problems/994805272659214336

PAT-ADVANCED1108

https://pintia.cn/problem-sets/994805342720868352/problems/994805360777347072

题目描述

PAT-BASIC1054

PAT-ADVANCED1108

知识点

字符串

思路

根据题述排除非法字符串

根据题意,排除以下几种字符串。

(1)字符串中有除了'-'、'.'、'0' ~ '9'之外的字符的。

(2)小数位数在2位以上的。

(3)在区间[-1000, 1000]之外的。

(4)有2个及以上小数点的。

注意点

对于其他的情况,诸如"+3"、"+3.0"、"3."、".3"、"-."、"."等均不需要考虑。在本题中"3."是合法的,如果把"3."判定非法,会导致测试点3通不过。

复杂度分析

时间复杂度是O(n),其中n为录入的数据字符串的总长度。空间复杂度是O(1)。

C++代码

#include<iostream>
#include<cstring>
#include<cmath>

bool isValid(char* input);	//判断输入的数字是否有效 
double changeToNum(char* input);	//将输入的数字转换成double类型 

int main() {
	int N;
	scanf("%d", &N);	//读取数字总数N	 
	char input[100];	//用char数组来记录每一个输入的数字 
	int count = 0;	//统计有效数字出现的个数 
	double sum = 0.0;	//统计有效数字总和 
	for(int i = 0; i < N; i++) {
		scanf("%s", input);
		if(isValid(input)) {	//如果输入的数字是有效的 
			count++;	//有效数字个数加1 
			sum += changeToNum(input);	//更新有效数字和 
		} else {
			printf("ERROR: %s is not a legal number\n", input);	//如果输入的数字是无效的,输出错误信息 
		}
	}
	if(count == 0) {	//如果没有有效数字出现 
		printf("The average of 0 numbers is Undefined\n");
	} else if(count == 1) {	//如果有效数字出现的次数是1 
		printf("The average of 1 number is %.2f\n", sum);
	} else {	//如果有效数字出现的次数大于等于2 
		printf("The average of %d numbers is %.2f\n", count, sum / count);
	}
	return 0;
}

bool isValid(char* input) {
	int len = strlen(input);
	int countPoint = 0;	//统计输入数字中小数点的个数 
	for(int i = 0; i < len; i++) {
		if(i == 0 && input[i] == '-') {	//对于输入数字中的第一个字符,允许是"-" 
			continue;
		}
		if(input[i] == '.') {	//遇到小数点 
			countPoint++;	//小数点个数加1 
		} else if(!(input[i] >= '0' && input[i] <= '9')) {	//如果遇到了0 ~ 9之外的字符,该数字一定不合法 
			return false;
		}
	}
	if(countPoint >= 2) {	//如果出现了2个及以上的小数点,该数字一定不合法 
		return false;
	}
	if(countPoint == 1) {	//如果小数点出现了一次 
		int pointIndex = strstr(input, ".") - input;	//寻找小数点的索引 
		if(len - 1 - pointIndex > 2) {	//如果小数点之后的字符数量大于2,说明该数字由大于2位的小数部分,该数字不合法 
			return false;
		}
	}
	double num = changeToNum(input);	//将该数字转换成double类型 
	if(num >= -1000 && num <= 1000) {	//如果该数字在[-1000, 1000]范围内,合法 
		return true;
	} else {	//如果该数字不在[-1000, 1000]范围内,不合法 
		return false;
	}
}

double changeToNum(char* input) {
	int len = strlen(input);
	if(strstr(input, ".")) {	//如果该数字中有小数点 
		int pointIndex = strstr(input, ".") - input;	//获得小数点的索引 
		if(input[0] == '-') {	//如果该数字第一个符号是"-" 
			double result = 0.0;
			for(int i = 1; i < pointIndex; i++) {	//从该数字的第二个符号,即索引1开始计算该数字整数部分的值 
				result = result * 10 + input[i] - '0';
			}
			for(int i = pointIndex + 1; i < len; i++) {	//从小数点索引后一位开始计算小数部分的值 
				result += (input[i] - '0') / (pow(10, i - pointIndex));
			}
			return -result;	//返回负的结果,因为该数字的第一个符号是"-" 
		} else {	 //如果该数字第一个符号不是"-" 
			double result = 0.0;
			for(int i = 0; i < pointIndex; i++) {	//从该数字的第一个符号,即索引0开始计算该数字整数部分的值 
				result = result * 10 + input[i] - '0';
			}
			for(int i = pointIndex + 1; i < len; i++) {	//从小数点索引后一位开始计算小数部分的值
				result += (input[i] - '0') / (pow(10, i - pointIndex));
			}
			return result;	//返回结果
		}
	} else {	//如果该数字中没有小数点,即没有小数部分 
		if(input[0] == '-') {	//如果该数字第一个符号是"-"
			double result = 0.0;
			for(int i = 1; i < len; i++) {	//从该数字的第二个符号,即索引1开始计算该数字的值 
				result = result * 10 + input[i] - '0';
			}
			return -result;	//返回负的结果,因为该数字的第一个符号是"-"
		} else {	//如果该数字第一个符号不是"-"
			double result = 0.0;
			for(int i = 0; i < len; i++) {	//从该数字的第一个符号,即索引0开始计算该数字的值 
				result = result * 10 + input[i] - '0';
			}
			return result;	//返回结果 
		}
	}
}

C++解题报告

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值