题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
#include <iostream> using namespace std; #include <string> #include <stack> #include <cctype> #include <map> void caculate(stack<int>& numS, stack<char>& opS) { int num2 = numS.top(); numS.pop(); int num1 = numS.top(); numS.pop(); char op = opS.top(); opS.pop(); switch (op) { case '+': numS.push(num1 + num2); break; case '-': numS.push(num1 - num2); break; case '*': numS.push(num1 * num2); break; case '/': numS.push(num1 / num2); break; } } int main() { string str; // 双栈法解决 stack<int> numS; stack<char> opS; // 设置计算符优先级 map<char, int> m; m.insert(pair<char, int>('+', 0)); m.insert(pair<char, int>('-', 0)); m.insert(pair<char, int>('*', 1)); m.insert(pair<char, int>('/', 1)); m.insert(pair<char, int>('(', -1)); getline(cin, str); int lastType = 0; // 记录上一个入栈的数据类型,用于识别负数 for (int i = 0; i < str.size(); i++) { if (isdigit(str[i])) { int b = i; while (isdigit(str[i])) { i++; } string str2(str.begin() + b, str.begin() + i); int num = stoi(str2); numS.push(num); i--; lastType = 1; } else if (str[i] == '(' || str[i] == '[' || str[i] == '{') { opS.push('('); lastType = 0; } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') { while (opS.top() != '(') { caculate(numS, opS); } opS.pop(); } else if (str[i] == '-') { if (lastType == 1) { while (!opS.empty() && m[opS.top()] >= m[str[i]]) { caculate(numS, opS); } opS.push(str[i]); lastType = 0; } else if (lastType == 0) { i++; int b = i; while (isdigit(str[i])) { i++; } string str2(str.begin() + b, str.begin() + i); int num = 0 - stoi(str2); numS.push(num); i--; lastType = 1; } } else { while (!opS.empty() && m[opS.top()] >= m[str[i]]) { caculate(numS, opS); } opS.push(str[i]); lastType = 0; } } while (!opS.empty()) { caculate(numS, opS); } cout << numS.top() << endl; }
双栈法,这里讲几个要点
第一:输入的数字不止个位数,要做好转化,这里用了str的一个构造方法;
第二:每准备入栈一个新的非左括号运算符之前,要判断一下这个新运算符与当前栈顶运算符的优先级,如果栈顶的运算符优先级大于或等于(一定要有等于)这个新运算符的优先级,则用这个栈顶符号做一次运算;运算过程可以写一个函数,优先级可以使用一个map;
第三:对于负数的读入,写一个标志位,如果上一个输入的符号为数字,则该‘-’符号是运算符;如果上一个输入的符号为运算符,则该‘-’符号代表负数的前缀;初始标志位为上一次输入为符号的状态;
第四:在字符串读入完成后,继续运算直到运算符栈为空后输出数字栈的栈顶元素即可。
建议理解的时候在纸张上画出栈帮助理解运行过程。
华为机试刷题记录 文章被收录于专栏
记录一下手打代码的解题思路方便复习