要是学过编译原理这题就比较好写了,但是不好想到。
简单算术表达式的上下文无关文法为:
exp--> exp addop term | term
addop--> + | -
term--> term mulop factor | factor
mulop--> * | /
factor --> (exp) | number
将文法化成EBNF范式,然后采用递归下降的方式求解exp的值:
cin.peek()函数看输入流中的下一个字符,但是不取走,真的好用。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<iomanip>
using namespace std;
double factor();
double term();
double exp();
double exp() //求表达式的值
{
double res=term();
while(true)
{
char op = cin.peek(); //看输入流中的下一个字符,不取走
if(op=='+' || op=='-')
{
cin.get(); //从输入流中取走一个字符
double val = term();
if(op=='+') res+=val;
else res-=val;
}else break;
}
return res;
}
double term()
{
double res=factor();
while(true)
{
char op = cin.peek();
if(op=='*' || op=='/')
{
cin.get();
double val = factor();
if(op=='*') res *= val;
else res /=val;
}else break;
}
return res;
}
double factor()
{
char c = cin.peek();
double res=0;
if(c=='(')
{
cin.get();
res = exp();
cin.get();
}else{
while(isdigit(c))
{
cin.get();
res = res*10+c-'0';
c=cin.peek();
}
if(c=='.') //有小数部分
{
double val=0;
double base = 0.1;
cin.get();
c=cin.peek();
while(isdigit(c))
{
cin.get();
val += (c-'0')*base;
c=cin.peek();
base = base * 0.1;
}
res += val;
}
}
return res;
}
int main()
{
double ans = exp();
cout<<fixed<<setprecision(2)<<ans<<endl;
return 0;
}