这道题的大意是让你求平均数,然而,输入中会包括一些不合法的数,这些数不能参与平均数的计算。这些不合法的数包括根本不是实数的字符串,以及虽然是实数,但是大小不在[-1000,1000]之内的数和小数位数超过2的数。
我这道题很快就做出来了,为什么要写一篇日记记录一下,是因为我在做这道题的时候应用了编译原理课上状态机处理常数的思想,利用状态机先判断当前的字符串是否是实数,如果是,再判断大小。这并不是什么算法知识,但是我个人感觉这种思想以后还会用到,因此记录一下。
除此之外,c++还有一个新特性被我应用了,那就是string直接转换为double的函数:stod()
,我在这道题里使用了long double,对应的函数即为stold()
,但是其实没必要开long double,我是因为开始WA了几次,想试试换个数据类型能不能过而已。如果是int,也有对应的函数:stoi()
,这个函数大大简化了这道题的代码量。
#include <iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<set>
#include<list>
#include<unordered_set>
using namespace std;
int n;
int num=0;
string s;
char temp[40];
long double ans=0;
bool isDigit(char k)
{
if(k>='0'&&k<='9')return true;
return false;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",temp);
s=temp;
int l=s.length();
int state=1;
bool isReal=true;
int digit=0;
for(int j=0;j<l;j++)
{
char cur=s[j];
if(state==1)
{
if(cur=='-'||isDigit(cur))
{
state=2;
}
else{
isReal=false;
break;
}
}
else if(state==2)
{
if(isDigit(cur))
{
continue;
}
else if(cur=='.')
{
state=3;
}
else{
isReal=false;
break;
}
}
else if(state==3)
{
if(isDigit(cur))
{
digit++;
continue;
}
else{
isReal=false;
break;
}
}
}
if(isReal==false||digit>2)
{
printf("ERROR: %s is not a legal number\n",temp);
continue;
}
else{
long double w=stold(s);
if(w>1000||w<-1000)
{
printf("ERROR: %s is not a legal number\n",temp);
continue;
}
else{
ans+=w;
num++;
}
}
}
if(num>0)
{
ans=ans*1.0/num;
if(num>1)
printf("The average of %d numbers is %.2Lf",num,ans);
else
printf("The average of %d number is %.2Lf",num,ans);
}
else{
printf("The average of 0 numbers is Undefined");
}
}