⭐PAT A1108 Finding Average

题目描述

在这里插入图片描述

知识点

字符串处理题

实现

码前思考

我的思想 很暴力 ,就是每次读一个字符串,然后遍历这个字符串来判断是否合法。

  1. 从非负号开始读起;
  2. 记录小数点出现的次数,一旦出现两个小数点,返回false
  3. 记录小数点前面的值和小数点后面的值的大小;
  4. 检查当前字符是不是数字和小数点,不是则返回false
  5. 小数点前后相加,如果超过范围,返回false,否则返回true

代码实现

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

const int maxn = 101;

int n;
int k;
double res;
char num[maxn];

bool judge(char num[]){
	//从字符的第一个符号开始判断
	//记录小数点的数量 
	int cnt = 0;
	int decimal = 0; 
	int len = strlen(num);
	double res = 0;
	double before = 0;
	double after = 0; 
	int start = 0;
	//首先判断第一个数字是否是负号
	if(num[0] == '-'){
		start = 1;
	}
	for(int i=start;i<len;i++){
		if(num[i]<'0'||num[i]>'9'){//如果当前位不是数字 
			//看是否是小数点
			if(num[i] == '.'){
				cnt++;
				if(cnt > 1){//如果有多个小数点了,返回false
					return false; 
				}
			}else{
				return false;
			} 
		}else{//如果当前位是数字 
			if(cnt!=1){ //小数点之前的数 
				before = before*10 + (num[i]-'0');
			}else{//小数点之后的数
				decimal++;
				if(decimal > 2){//超过两位 
					return false;
				} 
				after = after +  ((num[i]-'0')*pow(10,-decimal));
			} 
		} 
	} 		

	
	//得到最后的结果
	res = before + after;
	if(res>1000.00){
		return false;
	}else{
		return true;
	} 
}

int main(){
	scanf("%d",&n);
	k = 0;
	res = 0;
	for(int i=0;i<n;i++){
		//读入数据
		scanf("%s",num);
		//然后判断输入是否合法
		bool isLegal = judge(num); 
		if(isLegal){
			double val;
			sscanf(num,"%lf",&val);
			res += val;
			k++;
		}else{
			printf("ERROR: %s is not a legal number\n",num);
		}
	}
	
	if(k == 0){
		printf("The average of 0 numbers is Undefined\n");
	}else if(k == 1){
		printf("The average of 1 number is %.2f\n",res);
	}else{
		double avg = res/k;
		printf("The average of %d numbers is %.2f\n",k,avg);
	}
	
	return 0;
} 

码后反思

  1. 毫无疑问,上面的代码又臭又长,一道20分的题目,不应该需要这么长的时间的,我用了50min才写完,我实在是太菜了!

  2. 我的暴力解法里面想到了使用sprintsscanf,但是没有真正的用好它们,我看了柳婼的代码才恍然大悟,原来还可以这样用!下面是修改后的代码,简单了不止一点点:

    #include "bits/stdc++.h"
    using namespace std;
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	char a[50],b[50];
    	double tmp;
    	double sum = 0;
    	double avg = 0;
    	int cnt = 0;
    	
    	for(int i=0;i<n;i++){
    		bool flag = true;
    		scanf("%s",a);
    		sscanf(a,"%lf",&tmp);
    		sprintf(b,"%.2f",tmp);
    		for(int j=0;j<strlen(a);j++){
    			//之所以使用a的长度是为了保证5与5.00是相等的 
    			if(a[j] != b[j]){
    				flag = false;
    			}
    		}
    		if(flag == false || (tmp<-1000) || (tmp>1000)){
    			printf("ERROR: %s is not a legal number\n",a);
    		}else{
    			sum += tmp;
    			cnt++;
    		} 
    	}
    	
    	if(cnt == 0){
    		printf("The average of 0 numbers is Undefined\n");
    	}else if(cnt == 1){
    		printf("The average of 1 number is %.2f\n",sum);
    	}else if(cnt > 1){
    		avg = sum/cnt;
    		printf("The average of %d numbers is %.2f\n",cnt,avg);
    	} 
    	return 0;
    }
    
    • 之所以使用a的长度是为了保证5与5.00是相等的
    • 要在自己的心中过一遍下面这些情况,不要看代码简单,但是其中的情况还是复杂的:
      • 如果a是以字符开头,程序能正常执行吗?
      • 如果a是两位以上精度,程序能正常执行吗?
      • 如果a是整数,程序能正常执行吗?
  3. 需要认真的阅读题目,比如输出里面的number,有些是numbers,有些是number

  4. 另外我有一些关于输入的小疑惑,通过下面的实例来解决:

    int main(){
    	char str1[100] = "aa12aa";	//注意
    	char str2[100];
    	int a;
    	sscanf(str1,"%d",&a);
    	sprintf(str2,"%d",a);
    	printf("%d\n",a);
    	printf("%s\n",str1);
    	printf("%s\n",str2);
    	return 0;
    } 
    

    输出结果是什么呢?如下:
    在这里插入图片描述

    int main(){
    	char str1[100] = "12aaaa";	//注意
    	char str2[100];
    	int a;
    	sscanf(str1,"%d",&a);
    	sprintf(str2,"%d",a);
    	printf("%d\n",a);
    	printf("%s\n",str1);
    	printf("%s\n",str2);
    	return 0;
    } 
    

    输出结果是什么呢?
    在这里插入图片描述

    int main(){
    	char str1[100] = "        12aaaa";	//注意
    	char str2[100];
    	int a;
    	sscanf(str1,"%d",&a);
    	sprintf(str2,"%d",a);
    	printf("%d\n",a);
    	printf("%s\n",str1);
    	printf("%s\n",str2);
    	return 0;
    } 
    

    输出结果是什么呢?
    在这里插入图片描述

    int main(){
    	char str1[100] = "        12.1aaaa"; //注意
    	char str2[100];
    	double a;
    	sscanf(str1,"%lf",&a);
    	sprintf(str2,"%.2f",a);
    	printf("%lf\n",a);
    	printf("%s\n",str1);
    	printf("%s\n",str2);
    	return 0;
    } 
    

    得到什么结果呢?
    在这里插入图片描述

    综上,我们发现从字符串输入数字时,会忽略前面所有的空格和换行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值