表達式求值
時間限制: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
- 第一行輸入一個整數n,共有n組測試數據(n<10)。
/*表達式計算思路:從左到右遍歷中綴表達式中的每個數字和符號,若是數字則直接壓入數據棧中,若是符號(左括號直接入符號棧),則判斷其與棧頂符號的優先級,是右括號或優先級低于棧頂符號,則棧(符號棧即數據棧)中的元素依次出棧并計算,直到遇到左括號或棧頂元素優先級小于該符號壓入符號棧為止,最后符號棧依次出棧計算直至符號為空。
*/ #include "stdio.h"
#include "ctype.h"
#include "stack"
#define maxn 1000+10using namespace std;char buf[maxn];
stack<char> op; //符號隊列
stack<double> n; //得到操作符的優先級
int getValue(char c){ if('('==c) return 0; if('+'==c || '-'==c) return 1;if('*'==c || '/'==c) return 2;
}double calc(double a,double b,char c)
{
// printf("出棧操作:%f %c %f \n",a,c,b);switch(c){case '+': return (a+b);case '-': return (a-b);case '*': return (a*b);case '/': return (a/b);}
}//操作符出棧,即進行計算一次
void pull()
{ double a,b;if(n.size()>1 && !op.empty()){b=n.top(); n.pop();a=n.top(); n.pop();n.push(calc(a,b,op.top())); //printf("%d:出棧結果入棧!\n",n.size()); op.pop();// printf("符號:%d 數字: %d 出棧完畢!\n",op.size(),n.size());}
}int main()
{ int N,i;double d;char c;scanf("%d",&N);while(N--){ scanf("%s",buf); i=0;while(1){if(isalnum(buf[i])){sscanf(buf+i,"%lf",&d);n.push(d);// printf("%d:數字入棧:%lf\n",n.size(),d);while(isalnum(buf[i]) || '.'==buf[i]) i++; }c=buf[i++]; if('='==c || '\0'==c) break; if('('==c){op.push(c); // printf("(入棧\n");}else if(')'==c){while(!op.empty()){if('('==op.top()) {op.pop(); break; }pull();}}else{//注意先后順序,不為空才能進行op.top()操作 while( !op.empty() && getValue(c)<=getValue(op.top())) pull();op.push(c); //printf("%d:符號入棧:%c \n",op.size(),c);} } while(!op.empty()) pull(); printf("%.2lf\n",n.top()); while(!n.empty()) n.pop(); } return 0;
}