/*表達式求值
時間限制:3000 ms | 內存限制:65535 KB
難度:4
描述
ACM隊的mdd想做一個計算器,但是,他要做的不僅僅是一計算一個A+B的計算器,他想實現隨便輸入一個表達式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。
比如輸入:“1+2/4=”,程序就輸出1.50(結果保留兩位小數)
輸入
第一行輸入一個整數n,共有n組測試數據(n<10)。
每組測試數據只有一行,是一個長度不超過1000的字符串,表示這個運算式,每個運算式都是以“=”結束。這個表達式裏只包含+-與小括號這幾種符號。其中小括號可以嵌套使用。數據保證輸入的操作數中不會出現負數。
數據保證除數不會爲0
輸出
每組都輸出該組運算式的運算結果,輸出結果保留兩位小數。
樣例輸入
2
1.000+2/4=
((1+2)*5+1)/4=
樣例輸出
1.50
4.00*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stack>
using namespace std;
stack<char> csta;//字符棧
stack<double> dsta;//數據棧
char s[1010];
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
scanf("%s",&s[1]);
int len=strlen(&s[1]);
s[0]='(';
s[len]=')'; //'='改爲')'
for(int i=0;i<=len;i++)
{
if(s[i]=='(')//左括號先壓入
csta.push(s[i]);
else if(s[i]>='0' && s[i]<='9')
{
double t=0;
int b=0;
while(s[i]>='0' && s[i]<='9' || s[i]=='.')
{
if(s[i]=='.') //記錄小數點位置
b=i;
else
t=t*10+(s[i]-'0'); //轉成具體實數,小數乘10化整數
i++;
}
i--;
if(b!=0)
t/=pow(10,i-b); //如果有小數點轉成具體實數
dsta.push(t);
}
else if(s[i]=='+' || s[i]=='-') //先判斷後一級s[i]中的符號
{
double a,b,c;
while(csta.top()!='(') //在判斷字符棧中的符號
{
a = dsta.top(); dsta.pop(); //將實數取出棧,彈出棧中的數據
b = dsta.top(); dsta.pop();
switch(csta.top()) //後一級運算符是加減的話,前一級運算符不論爲什麼都是先運算
{
case '+':c=a+b;break;
case '-':c=b-a;break;
case '*':c=b*a;break;
case '/':c=b/a;break;
}
dsta.push(c); //將運算結果壓進棧
csta.pop(); //彈出運算後的運算符
}
csta.push(s[i]);
}
else if(s[i]=='*' || s[i]=='/') //先判斷後一級s[i]中的符號
{
double a,b,c;
if(csta.top()=='*' || csta.top()=='/') //後一級運算符是 * / 的話,前一級也需要是 * / 才能先運算前一級
{
a = dsta.top(); dsta.pop();
b = dsta.top(); dsta.pop();
switch(csta.top())
{
case '*':c=b*a;break;
case '/':c=b/a;break;
}
dsta.push(c);//將運算結果壓進棧
csta.pop();//彈出運算後的運算符
}
csta.push(s[i]);
}
else if(s[i]==')')//後一級運算符是 ) 的話,把()裏的結果運算出來
{
double a,b,c;
while(csta.top()!='(')
{
a = dsta.top(); dsta.pop();
b = dsta.top(); dsta.pop();
switch(csta.top())
{
case '+':c=a+b;break;
case '-':c=b-a;break;
case '*':c=b*a;break;
case '/':c=b/a;break;
}
dsta.push(c); //將運算結果壓進棧
csta.pop(); //彈出運算後的運算符
}
csta.pop(); //彈出棧中的'('
}
}
printf("%.2lf\n",dsta.top()); //輸出運算後的運算符
dsta.pop(); //彈出棧中的結果
}
return 0;
}