思路與“中綴表達式轉後綴表達式”相似
#include <iostream>
#include <cstring>
#include <stack>
#include <cmath>
using namespace std;
stack<double> num;
stack<char> oprt;
char s[1005];
int l = 0;
void in(){
char t[1005];
cin.getline(t, 1000);
int ll = strlen(t);
for(int i = 0; i < ll; ++i){
if(t[i] != ' '){
s[l++] = t[i];
}
}
}
double cal(double a, double b, char o){
if(o == '+') return a+b;
if(o == '-') return a-b;
if(o == '*') return a*b;
if(o == '/') return a/b;
else{
cerr << "error" << endl;
}
}
int main()
{
in();
int i = 0;
while(i < l){
if(isdigit(s[i]) || s[i] == '.'){
double b = 0;
while(i < l && isdigit(s[i])){
b *= 10;
b += s[i++] - '0';
}
if(s[i] == '.'){
++i;
int ct = 0;
while(i < l && isdigit(s[i])){
b += (s[i++]-'0') * pow(0.1, ++ct);
}
}
num.push(b);
}
else{
switch(s[i]){
case '+':
case '-':
while(!oprt.empty() && oprt.top() != '('){ // 如果用if,那麼形如“1+2*3+”的式子就不能正常處理
double b = num.top(); num.pop();
double a = num.top(); num.pop();
num.push(cal(a,b,oprt.top())); oprt.pop();
}
oprt.push(s[i]);
break;
case '*':
case '/':
if(!oprt.empty() && (oprt.top() == '*' || oprt.top() == '/')){
double b = num.top(); num.pop();
double a = num.top(); num.pop();
num.push(cal(a,b,oprt.top())); oprt.pop();
}
oprt.push(s[i]);
break;
case '(':
oprt.push(s[i]);
break;
case ')':
while(!oprt.empty() && oprt.top() != '('){
double b = num.top(); num.pop();
double a = num.top(); num.pop();
num.push(cal(a,b,oprt.top())); oprt.pop();
}
oprt.pop(); // '('
break;
}
++i;
}
}
while(!oprt.empty()){
double b = num.top(); num.pop();
double a = num.top(); num.pop();
num.push(cal(a,b,oprt.top())); oprt.pop();
}
printf("%.2f\n", num.top());
system("pause");
return 0;
}