PAT (Advanced Level) Practice 1108 Finding Average 指定格式字符串筛选

一、概述

20分的题,我做了一小时还没AC,气死。原因在于不知道有两个很好用的函数。这两个函数在筛选指定格式字符串时很好用。

sscanf(char[],"格式",&int/float....);

sscanf的参数如图,第一个参数是一个字符数组a,第二个参数是格式,参照正常的scanf的格式,第三个就是我们要把从字符串中取出的符合格式的东西保存的变量了。

sprintf(char[],"格式",int/float....);

sprintf和sscanf的参数相似,字符数组a,格式,某一变量b;但是是将b按格式转化为字符串存在a中。

因此这两个函数一起使用,就可以筛选出满足条件的所有字符串了:

输入为s,按条件找出a,将a按条件变成_s,如果_s和s相等,那么说明这个s是我们要的格式,如果不相等,说明不是。

实际上sscanf有更强大的功能。

例如使用%[1-9]来读入所有数字,使用%[^A-Z]来实现遇到大写字母停止读取的功能等。

要熟练掌握。

二、分析

由于最开始我不知道这俩好用的函数,因此没给我气死。

使用string,一位一位看,有字母那就扔掉,遇到小数点,小数点后面数字计数,计数大于两个也扔掉,多于一个小数点也扔掉——这么多条件想筛完很麻烦不说,还容易漏掉别的条件,谁知道里面是不是会有@#¥@%¥……#%¥%什么之类的。

那么选择使用sscanf和sprintf。注意到他们都需要使用字符数组。那么先开两个字符数组。

注意到我们只要保留两位小数的小数和整数,那么这就是我们要的格式。如下:

scanf("%s",a);
double temp;
sscanf(a,"%lf",&temp);
sprintf(b,"%.2lf",temp);
int flag=0;
int length=strlen(a);
for(int j=0;j<length;j++)
{
	if(a[j]!=b[j])
	{
		flag=1;
		break;
	}
}

先用a保存输入的字符串,然后用temp保存在a中的数,然后把temp转换为保留两位小数的数并转换为字符串。

那么如果输入真的是一个有两位小数的数或者整数,这一套下来应该没有变化,如果有变化,那么说明不符合要求。这样就实现了筛选。然后计算并输出即可。

三、总结

简直要哭瞎。两个函数顶了我120行的代码。

PS:我的代码:懒得debug,未AC

#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
double stringtodouble(string a,int afterpoint)
{
	double num=0;
	if(afterpoint==0)//说明是整数
	 {
	 	if(a[0]=='-')//说明是负数
		  {
		  	string::reverse_iterator it1;
		  	int index=0;
		  	for(it1=a.rbegin();it1!=a.rend()-1;it1++)
		  		{
		  			num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
				}
			return -num;
		  }
		else//说明是正数
		{
			string::reverse_iterator it1;
		  	int index=0;
		  	for(it1=a.rbegin();it1!=a.rend();it1++)
		  		{
		  			num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
				}
			return num;
		}  
	 }
	else if(afterpoint==2)//说明是小数 
	 {
	 	if(a[0]=='-')//说明是负数
		  {
		  	string::reverse_iterator it1;
		  	int index=-2;
		  	for(it1=a.rbegin();it1!=a.rend()-1;it1++)
		  		{
		  			if(*it1=='.')
					  continue;
					else
		  			{
					  num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
		  			}
				}
			return -num;
		  }
		else//说明是正数
		{
			string::reverse_iterator it1;
		  	int index=-2;
		  	for(it1=a.rbegin();it1!=a.rend();it1++)
		  		{
		  			if(*it1=='.')
					  continue;
					else
		  			{
					  num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
		  			}
				}
			return num;
		}
	  }
	  else
	  {
	  	if(a[0]=='-')//说明是负数
		  {
		  	string::reverse_iterator it1;
		  	int index=-1;
		  	for(it1=a.rbegin();it1!=a.rend()-1;it1++)
		  		{
		  			if(*it1=='.')
					  continue;
					else
		  			{
					  num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
		  			}
				}
			return -num;
		  }
		else//说明是正数
		{
			string::reverse_iterator it1;
		  	int index=-1;
		  	for(it1=a.rbegin();it1!=a.rend();it1++)
		  		{
		  			if(*it1=='.')
					  continue;
					else
		  			{
					  num+=(*it1-'0')*pow(10,index);
		  			index++;
		  			if(num>1000)
		  				return num;
		  			}
				}
			return num;
		}
	   } 
}
int main()
{
	int N;
	scanf("%d",&N);
	double sum=0;
	int num=0;
	for(int i=0;i<N;i++)
	{
		string input;
		cin>>input;
		string::iterator iter;
		int pointnum=0;
		int afterpoint=0;
		int valid=1;
		for(iter=input.begin();iter!=input.end();iter++)
		{
			if(*iter=='-'&&iter==input.begin())
			continue;
			else if((*iter>='0'&&*iter<='9')||*iter=='.')//合格
			{
				if(*iter=='.')
				{
					pointnum++;
					if(pointnum>1)
					{
						valid=0;
						break;
					}
					continue;
				}
				else if(pointnum==1)
				{
					afterpoint++;
					if(afterpoint>2)
					{
						valid=0;
						break;
					}
				}
			}
			else
				{
					valid=0;
					break;
				 } 
		}
		if(pointnum==1&&afterpoint==0)
			valid=0;
		if(valid==1)
		{
			double addon=stringtodouble(input,afterpoint);
			if(addon>1000||addon<-1000)
			{
				cout<<"ERROR: "<<input<<" is not a legal number"<<'\n';
				continue;
			}
			num++;
			sum+=addon;
			afterpoint=0;
		}
		else
		cout<<"ERROR: "<<input<<" is not a legal number"<<'\n';	
	}
	if(num==0)
	cout<<"The average of 0 numbers is Undefined";
	else if(num==1)
	printf("The average of 1 number is %.2lf",sum);
	else
	{
		double ans=sum/num;
		printf("The average of %d numbers is %.2lf",num,ans);
	}
}

AC代码如下:

#include<stdio.h>
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
char a[50],b[50];
int main()
{
	int N;
	scanf("%d",&N);
	double sum=0;
	int num=0;
	for(int i=0;i<N;i++)
	{
		scanf("%s",a);
		double temp;
		sscanf(a,"%lf",&temp);
		sprintf(b,"%.2lf",temp);
		int flag=0;
		int length=strlen(a);
		for(int j=0;j<length;j++)
		{
			if(a[j]!=b[j])
			{
				flag=1;
				break;
			}
		}
		if(flag==1||temp>1000||temp<-1000)
			printf("ERROR: %s is not a legal number\n",a);
		else
		{
			num++;
			sum+=temp;
		}
	}
	if(num==0)
	cout<<"The average of 0 numbers is Undefined";
	else if(num==1)
	printf("The average of 1 number is %.2lf",sum);
	else
	{
		double ans=sum/num;
		printf("The average of %d numbers is %.2lf",num,ans);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值