题目描述
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
你可以假设给定的表达式总是有效的。所有中间结果将在
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()
。
示例 1
输入:s = "3+2*2"
输出:7
示例 2
输入:s = " 3/2 "
输出:1
示例 3
输入:s = " 3+5 / 2 "
输出:5
提示
- 1 <= s.length <= 3 *
-
s
由整数和算符 ('+', '-', '*', '/')
组成,中间由一些空格隔开 -
s
表示一个 有效表达式 - 表达式中的所有整数都是非负整数,且在范围
- 题目数据保证答案是一个 32-bit 整数
题目分析
学过数据结构的都应该玩过这道题类似的练习,这里使用栈解决很方便,这道题还比较容易,没有考虑到括号的情况。你可以使用双栈(运算数栈和运算符栈)或者单栈(一边遍历字符串,一边计算结果压栈)来解决这道题。甚至你可以使用逆波兰式求解。下面的解法就是使用单栈的方法,遍历字符串的同时,遇到加法和减法运算符就把元素压入栈,遇到乘法和除法运算符就把栈顶元素弹出栈并计算结果,把结果压入栈,最后只需要把栈中的所有元素加起来,就是最终的答案了。
题解
执行用时: 13 ms
内存消耗: 44.5 MB
class Solution {
public int calculate(String s) {
// 存储运算数的栈
Deque<Integer> stack = new LinkedList<>();
// 运算符
char preSign = '+';
// 临时变量 获取字符串中的运算数
int num = 0;
// 字符串长度
int length = s.length();
// 遍历字符串
for (int i = 0; i < length; ++i) {
// 当前字符是数字
if (Character.isDigit(s.charAt(i))) {
// 获取、更新当前运算数
num = num * 10 + s.charAt(i) - '0';
}
// 当前字符非数字(空格、运算符)
if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == length - 1) {
// 根据运算符进行运算并将结果压入栈
switch (preSign) {
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
case '*':
stack.push(stack.pop() * num);
break;
default:
stack.push(stack.pop() / num);
break;
}
// 更新运算符
preSign = s.charAt(i);
// 运算数恢复初值
num = 0;
}
}
// 遍历栈将每个元素相加即为结果
int res = 0;
while (!stack.isEmpty()) {
res += stack.pop();
}
return res;
}
}
题目来源:力扣(LeetCode)