题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
#include <cctype> #include <iostream> #include <vector> #include <string> #include <stack> using namespace std; double dealWithOperator(double a, double b, char c) { if (c == '+') return a + b; else if (c == '-') return a - b; else if (c == '*') return a * b; else if (c == '/') return a / b; return 0; } int priority(char c) { if (c == '+' || c == '-') return 1; else if (c == '*' || c == '/') return 2; else if (c == '(') return 3; return -1; } double stringExpression2result(string& s) { for (char& i : s) { if (i == '{' || i == '[') i = '('; else if (i == '}' || i == ']') i = ')'; } stack<char> os; stack<string> num; //利用string来储存数值也是一个好思路 //经典算法,双栈法,利用两个栈,一个用于处理操作数,一个用于处理预算符号 double out = 0; for (int i = 0; i != s.size(); ++i) { if (s[i] == ' ') continue; if (isdigit(s[i])) { string number; while (i != s.size() && isdigit(s[i])) { number += s[i]; ++i; } --i;//上一步额外的加了一次 num.push(number); } else if (s[i] == '(') { //遇到左括号(进行压栈 os.push(s[i]); } else if (s[i] == ')') { while (!os.empty() && os.top() != '(') { //处理括号内的内容 double num1 = stod(num.top()); num.pop(); double num2 = stod(num.top()); num.pop(); char op = os.top(); os.pop(); num2 = dealWithOperator(num2, num1, op); num.push(to_string(num2)); } if (!os.empty()) //弹出'(' os.pop(); } else { //如何处理运算符 if (s[i] == '-') { if (isdigit(s[i + 1]) && (i == 0 || s[i - 1] == '(')) { string k(1, '-'); k += s[i + 1]; num.push(k); i++; continue; } } if (!os.empty()) { int pot = priority(os.top()); int pon = priority(s[i]); if (pot >= pon && pot != 3) { // dirctly compute double n1 = stod(num.top()); num.pop(); double n2 = 0; // if there isn't a second number in num // might be the first number is a negative number if (!num.empty()) { n2 = stod(num.top()); num.pop(); } char op = os.top(); os.pop(); if (!os.empty() && os.top() == '-' && op == '-') { n2 = dealWithOperator(n2, n1, '+'); num.push(to_string(n2)); } else { n2 = dealWithOperator(n2, n1, op); num.push(to_string(n2)); } } } os.push(s[i]); } } while (!os.empty()) { double num1 = stod(num.top()); num.pop(); double num2 = stod(num.top()); num.pop(); char op = os.top(); os.pop(); num2 = dealWithOperator(num2, num1, op); num.push(to_string(num2)); } out = stod(num.top()); return out; } int main() { string s; getline(cin, s); cout << stringExpression2result(s); } // 64 位输出请用 printf("%lld")
这个题的核心在于要利用FILO的stack操作,因为有括号的存在,每次遇到")"就要从后往前一直推到"("为止,利用双栈法,一个储存数字,一个储存符号,但是值得注意的是两个,一个-n或者(-n的负数情况,另一个是-6-3+2的时候按照堆栈的做法是6-3,这样是错误的,需要额外一个判断