基本计算器类问题(栈)
150. 逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入: ["4", "13", "5", "/", "+"]
输出: 6
解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
输出: 22
解释:
该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
这题算是较为简单的题了,不用考虑顺序问题,用一个stack就可以解决。
每次读到符号时,从栈中弹出两个数据进行相应的运算,之后再存在栈中即可。
class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> sta; int n = tokens.size(); int fir,sec; for(int i = 0; i < n; i++){ if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){ sec = sta.top(); sta.pop(); fir = sta.top(); sta.pop(); if(tokens[i] == "+") sta.push(fir + sec); else if(tokens[i] == "-") sta.push(fir - sec); else if(tokens[i] == "*") sta.push(fir * sec); else sta.push(fir / sec); } else{ int length = tokens[i].size(); string temp = tokens[i]; int j = 0,sign = 1,sum = 0; while(j < length){ if(temp[j] == '-' || temp[j] == '+'){ if(temp[j] == '-') sign = -1; else sign = 1; } else{ sum = sum * 10 + temp[j] - 48; } j++; } sum *= sign; sta.push(sum); } } return sta.top(); } };
224. 基本计算器
实现一个基本的计算器来计算一个简单的字符串表达式 s 的值。
示例 1:
输入:s = "1 + 1"
输出:2
示例 2:
输入:s = " 2-1 + 2 "
输出:3
示例 3:
输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23
因为没有乘法的除法,因此,如果展开表达式中所有的括号,则得到的新表达式中,数字本身不会发生变化,只是每个数字前面的符号会发生变化。
因此,我们考虑使用一个取值为 {-1,+1} 的整数 sign代表「当前」的符号。根据括号表达式的性质,它的取值:
与字符串中当前位置的运算符有关;
如果当前位置处于一系列括号之内,则也与这些括号前面的运算符有关:每当遇到一个以 - 号开头的括号,则意味着此后的符号都要被「翻转」
class Solution { public: int calculate(string s) { int n = s.size(); int sign = 1; stack<int> sta; sta.push(1); int sum = 0,i = 0; while(i < n){ switch(s[i]){ // 遇到括号把前面的符号存起来,如果是-1的话括号里面的数都乘-1 case ' ' : i++; break; case '+' : sign = sta.top(); i++; break; case '-' : sign = -sta.top(); i++; break; case '(' : sta.push(sign); i++; break; case ')' : sta.pop(); i++; break; default : long temp = 0; while(i < n && s[i] >= '0' & s[i] <= '9'){ temp = temp * 10 + s[i] - 48; i++; } sum += temp * sign; cout << sum; break; } } return sum; } };
227. 基本计算器 II
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: "3+2*2"
输出: 7
示例 2:
输入: " 3/2 "
输出: 1
示例 3:
输入: " 3+5 / 2 "
输出: 5
这道题多了* 和 / ,所以需要考虑优先级的问题,我们可以在遇到一个数字结束后(有可能是遇到符号,或者空格,或者是字符串的末尾),把之前存取在sign的符号取出来
如果是'+': 就把当前数字存到栈里
如果是’-‘: 就把当前数字取反存到栈里
如果是’*’: 把当前数字和之前存到栈里的数字相乘后存到栈里
如果是‘/’: 把当前数字和之前存到栈里的数字相除后存到栈里
class Solution { public: int calculate(string s) { int n = s.size(); char sign = '+'; stack<int> num; int cur = 0; int sum = 0; int temp; for(int i = 0; i < n; i++){ if(s[i] >= '0'){ //cur 是当前正在遍历的数字 cur = cur * 10 - 48 + s[i]; } //当前的数字过了,需要处理一下之前的sign和cur if(s[i] < '0' && s[i] != ' ' || i == n - 1){ //上一个保存的符号 switch(sign){ case '+' : num.push(cur); break; case '-' : num.push(-cur); break; case '*' : temp = num.top(); num.pop(); num.push(temp * cur); break; case '/' : temp = num.top(); num.pop(); num.push(temp / cur); break; } // 保存这次的符号 sign = s[i]; cur = 0; } } while(!num.empty()){ sum += num.top(); num.pop(); } return sum; } };
浙公网安备 33010602011771号