#include <iostream> #include <cstdio> #include <string> #include <algorithm> #include <stack> #include <map> using namespace std; /** * 中缀表达式转后缀表达式(逆波兰式) * @param formula * @return */ string getRPN(string formula); /** * 后缀表达式求值 * @param rpnFormula * @return */ double getRPNRes(string rpnFormula); /** * 计算运算符的操作结果 * @param opera 运算符 * @param leftNum 左操作数 * @param rightNum 右操作数 * @return */ double calculate(char opera, double leftNum, double rightNum); /** * map存放运算符的优先级 */ map<char, int> priority = { {'$', 0}, //结尾符$--1 {'+', 1}, //加--1 {'-', 1}, //减--1 {'*', 2}, //乘--2 {'/', 2} //除--2 }; /** * 简单计算器--浙江大学 * @return */ int main() { string str; while (getline(cin, str)) { if (str == "0") { break; } //在字符串的结尾添加"$" str += "$"; string formula = getRPN(str); double res = getRPNRes(formula); printf("%.2f\n", res); //cout << formula << endl; //cout << res << endl; } return 0; } string getRPN(string formula) { stack<char> operaStack; string res = ""; string num = ""; for (int i = 0; i < formula.size(); ++i) { char character = formula[i]; if (character == '$') { //来到最后一个字符$ //将num加入道后缀表达式中 res += num; res += " "; //将字符栈中剩余的运算符加入道后缀表达式中 while (!operaStack.empty()) { res += operaStack.top(); operaStack.pop(); res += " "; } } else if (character == ' ') { //空格, 则表示一个单位已经扫描完 if (num != "") { res += num; res += " "; num = ""; } } else if ('0' <= character && character <= '9' || character == '.') { //数字 num.push_back(character); } else if (('a' <= character && character <= 'z') || ('A' <= character && character <= 'Z')) { res += character; res += " "; } else if (character == '(') { //"(", 则直接入栈 operaStack.push(character); } else if (character == ')') { //")", 则弹出栈内的运算符,并加入到后缀表达式中,直至弹出"(" while (!operaStack.empty() && operaStack.top() != '(') { res += operaStack.top(); operaStack.pop(); res += " "; } } else { /* * 运算符 * 依次弹出所有优先级高于或者等于当前运算符的运算符,并将其加入到后缀表达式中。 */ while (!operaStack.empty() && priority[operaStack.top()] >= priority[character]) { res += operaStack.top(); operaStack.pop(); res += " "; } //当前运算符入栈 operaStack.push(character); } } return res; } double getRPNRes(string formula) { stack<double> numStack; string num = ""; for (int i = 0; i < formula.size(); ++i) { char character = formula[i]; if (character == ' ') { if (num != "") { numStack.push(stod(num)); num = ""; } } else if ('0' <= character && character <= '9' || character == '.') { num.push_back(character); } else { double rightNum = numStack.top(); numStack.pop(); double leftNum = numStack.top(); numStack.pop(); numStack.push(calculate(character, leftNum, rightNum)); } } if (numStack.size() == 1) { return numStack.top(); } else { return -1; } } double calculate(char opera, double leftNum, double rightNum) { double res = 0; switch (opera) { case '+': res = leftNum + rightNum; break; case '-': res = leftNum - rightNum; break; case '*': res = leftNum * rightNum; break; case '/': res = leftNum / rightNum; break; default: break; } return res; }