题解 | 四则运算
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
#include <iostream> #include <cstring> #include <stack> #include <cctype> #include <sstream> using namespace std; // 判断是否为左括号 bool is_left(char c) { return c == '(' || c == '[' || c == '{'; } // 判断是否为右括号 bool is_right(char c) { return c == ')' || c == ']' || c == '}'; } // 判断左右括号是否匹配 bool pair_bracket(char c, char stacktop) { if (c == ')' && stacktop == '(') return true; if (c == ']' && stacktop == '[') return true; if (c == '}' && stacktop == '{') return true; return false; } // 比较栈顶操作符与当前操作符的优先级 bool priority(char stacktop, char c) { // 这里c已经筛去括号 // true: 栈顶优先级高 // false: 当前字符优先级高 if (is_left( stacktop)) // 右括号不进栈,直接走,所以不考虑右括号在栈顶的情况,且此处c不会是括号 return false; if (stacktop == '*' || stacktop == '/') // 栈顶乘除一定大于等于当前符号 return true; if (stacktop == '+' || stacktop == '-') { if (c == '+' || c == '-') return true; return false; } return false; } // 将中缀表达式转换为后缀表达式 string infixTopostfix(string infix) { stack<char> myStack; string postfix; string number; for (size_t i = 0; i < infix.length(); i++) { char c = infix[i]; if (isdigit(c) || ('-' == c && !is_right(infix[i - 1]) && (number.empty() || is_left(infix[i - 1])))) { // 如果前一个是右括号,这里也一定不是负号,需要排除 number += c; // 只把数字和负号给number if (i == infix.length() - 1) postfix += number + ' '; continue; } if (!number.empty()) { // 如果c不再是数字,意味着number结束了,交付给后缀表达式 postfix += number + ' '; number.clear(); } if (is_left(c)) { // 左括号无脑进栈 myStack.push(c); } else if (is_right(c)) { // 右括号判断逻辑应先于加减乘除符号 while (!myStack.empty() && !pair_bracket(c, myStack.top())) { // 遇到右括号后一直出栈至配对左括号 postfix += myStack.top(); postfix += ' '; myStack.pop(); } if (!myStack.empty()) myStack.pop(); // 弹出左括号 } else { // 到这里就只有加减乘除操作符了 if (myStack.empty()) { myStack.push(c); continue; } while (!myStack.empty() && priority(myStack.top(), c)) { // 栈顶符号优先级>=当前c时先依次出栈栈顶符号,直至当前符号c优先级大于栈顶符号(如加减遇到括号,乘除遇到加减) postfix += myStack.top(); postfix += ' '; myStack.pop(); } myStack.push(c); // 栈顶符号优先级小于当前符号,则直接入栈 } } while (!myStack.empty()) { postfix += myStack.top(); postfix += ' '; myStack.pop(); } return postfix; } int main() { string s; stack<int> ans; // 改为 int 类型以支持整数运算 getline(cin, s); string postfix = infixTopostfix(s); // 中缀表达式转后缀表达式 // 计算后缀表达式 stringstream ss(postfix); string token; try { while (ss >> token) { // 使用字符串流读取包含空格的后缀表达式 if (isdigit(token[0]) || (token[0] == '-' && token.size() > 1)) { // 数字和负数 ans.push(stoi(token)); // 转换为整数 } else { int a = ans.top(); ans.pop(); int b = ans.top(); ans.pop(); int res = 0; switch (token[0]) { // 注意switch只能匹配字符或整型、枚举类型 case '+': res = b + a; break; case '-': res = b - a; break; case '*': res = b * a; break; case '/': if (a == 0) throw runtime_error("Division by zero"); // 添加除零检测 res = b / a; break; default: throw runtime_error("Invalid operator"); } ans.push(res); } } if (ans.size() != 1) throw runtime_error("Invalid expression"); cout << ans.top(); } catch (const exception& e) { cerr << "Error: " << e.what() << endl; return 1; } return 0; }