【算法】【线性表】【字符串】基本计算器 II
1 题目
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1]
的范围内。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()
。
示例 1:
输入:s = "3+2*2"
输出:7
示例 2:
输入:s = " 3/2 "
输出:1
示例 3:
输入:s = " 3+5 / 2 "
输出:5
提示:
1 <= s.length <= 3 * 105
s
由整数和算符('+', '-', '*', '/')
组成,中间由一些空格隔开s
表示一个 有效表达式- 表达式中的所有整数都是非负整数,且在范围
[0, 231 - 1]
内 - 题目数据保证答案是一个 32-bit 整数
2 解答
这道题着实对我有点难度,我以前知道表达式的计算,是用栈的压栈弹栈实现的,我记得是后缀表达式如果是数字直接压栈,如果碰到运算符就弹出两个数然后进行运算,然后将运算的结果再压栈,莫非这个要将表达式变成后缀表达式么?哈哈哈。题中的表达式是个中序表达式,这个该怎么利用栈计算呢?这个是用的数字前缀来做的,你比如 3 + 2 * 2 就是 +3 + 2 * 2 每个数都是根据它前边的前缀来判断是做什么操作的,如果是加减就压栈,如果是乘除就把栈顶的数和当前的数运算然后压进去,代码如下:
class Solution { public int calculate(String s) { // 当前获取到的数字 int currentNum = 0; // 当前数的前缀操作默认+ char preSign = '+'; // 核心思想就是通过一个栈来进行计算,乘除运算 加减放进栈中,最后将栈中的元素都加起来就是表达式的结果 Deque<Integer> stack = new ArrayDeque<>(); int len = s.length(); for (int i = 0; i < len; i++) { char c = s.charAt(i); // 空格直接略过 if (c == ' ') continue; // 如果是数字的话,先读取一个数 if (Character.isDigit(c)) { // 这个我还是看的题解= = 因为它表达式不仅仅是个数 他还有 10 + 300 + 345 这种多位的数 所以每次都是 乘10 加上个位数 currentNum = currentNum * 10 + c - '0'; continue; } // 到这里 currentNum 就是一个完整的数字了 并且是个操作符了 operate(stack, preSign, currentNum); preSign = c; currentNum = 0; } // 最后一位没参与运算呢还 operate(stack, preSign, currentNum); // 求和 int res = 0; while (!stack.isEmpty()) { res += stack.pop(); } return res; } private void operate(Deque<Integer> stack, char preSign, int currentNum) { switch (preSign) { // 如果是加减的话 则直接把 currentNum 放进去 case '+': { stack.push(currentNum); } break; case '-': { stack.push(-currentNum); } break; // 这里说明是乘除了 那就从把栈顶的取出来和 currentNum 进行运算,然后将运算结果放里边 case '*': { stack.push(stack.pop() * currentNum); } break; case '/': { stack.push(stack.pop() / currentNum); } break; default: {} } } }
加油。