要是学过编译原理这题就比较好写了,但是不好想到。
简单算术表达式的上下文无关文法为:
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; }