表示式求值(逆波蘭式)
阿新 • • 發佈:2019-01-06
表示式求值
時間限制: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
/* * 這裡主要是逆波蘭式的實現,使用兩個stack 這裡用字串來模擬一個stack,第一步,將中綴表示式轉變為字尾表示式 * 第二步,然後再使用一個stack,計算字尾表示式的結果,這一步很容易出錯,考慮到浮點數的問題。 */ #include <iostream> #include <string> #include <stack> #include <iomanip> using namespace std; int cmp(char ch) // 運算子優先順序 { switch(ch) { case '+': case '-': return 1; case '*': case '/': return 2; default : return 0; } } void change(string &s1, string &s2) // 中綴表示式轉變字尾表示式 { stack <char > s; s.push('#'); int i = 0; while(i < s1.length()-1) { if(s1[i] == '(') { s.push(s1[i++]); } else if(s1[i] == ')') { while(s.top() != '(') { s2 += s.top(); s2 += ' '; s.pop(); } s.pop(); i++; } else if(s1[i] == '+'||s1[i] == '-'||s1[i] == '*'||s1[i] == '/') { while(cmp(s.top()) >= cmp(s1[i])) { s2 += s.top(); s2 += ' '; s.pop(); } s.push(s1[i]); i++; } else { while('0' <= s1[i]&&s1[i] <= '9'||s1[i] == '.') { s2 += s1[i++]; } s2 += ' '; } } while(s.top() != '#') { s2 += s.top(); s2 += ' '; s.pop(); } } double value(string s2) // 計算字尾表示式,得到其結果。 { stack < double> s; double x,y; int i = 0; while(i < s2.length()) { if(s2[i] == ' ') { i++; continue; } switch(s2[i]) { case '+': x = s.top(); s.pop(); x += s.top(); s.pop(); i++; break; case '-': x = s.top(); s.pop(); x =s.top()-x; s.pop(); i++; break; case '*': x = s.top(); s.pop(); x *= s.top(); s.pop(); i++; break; case '/': x = s.top(); s.pop(); x = s.top()/x; s.pop(); i++; break; default : { x = 0; while('0' <= s2[i]&&s2[i] <= '9') { x = x*10+s2[i] - '0'; i++; } if(s2[i] == '.') { double k = 10.0; y = 0; i++; while('0' <= s2[i]&&s2[i] <= '9') { y += ((s2[i]-'0')/k); i++; k *= 10; } x += y; } } } s.push(x); } return s.top(); } int main(int argc, char const *argv[]) { int n; string s1,s2; cin>>n; while(n--) { cin>>s1; s2 = ""; change(s1,s2); cout<<fixed<<setprecision(2)<<value(s2)<<endl; } return 0; }