计算器
难度:
标签:
题目描述
Given an arithmetic equation consisting of positive integers, +, -, * and / (no parentheses), compute the result.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.
Example 1:
Input: "3+2*2" Output: 7
Example 2:
Input: " 3/2 " Output: 1
Example 3:
Input: " 3+5 / 2 " Output: 5
Note:
- You may assume that the given expression is always valid.
- Do not use the eval built-in library function.
代码结果
运行时间: 54 ms, 内存: 17.9 MB
/*
* 思路:
* 1. 使用栈来存储数字和计算结果。
* 2. 使用变量来保存当前的数字和运算符。
* 3. 遍历字符串,当遇到数字时,进行累加。
* 4. 当遇到运算符时,根据上一个运算符和当前数字进行操作。
* 5. '+' 和 '-' 将当前数字压入栈中('+' 直接压入,'-' 取负后压入)。
* 6. '*' 和 '/' 取出栈顶数字进行运算后再压入。
* 7. 最后将栈中的所有数字相加得到最终结果。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Calculator {
public int calculate(String s) {
Stack<Integer> stack = new Stack<>();
int num = 0;
char sign = '+';
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
}
if (!Character.isDigit(c) && c != ' ' || i == s.length() - 1) {
if (sign == '+') {
stack.push(num);
} else if (sign == '-') {
stack.push(-num);
} else if (sign == '*') {
stack.push(stack.pop() * num);
} else if (sign == '/') {
stack.push(stack.pop() / num);
}
sign = c;
num = 0;
}
}
return stack.stream().collect(Collectors.summingInt(Integer::intValue));
}
}
解释
方法:
此题解采用了一个栈来处理没有括号的四则运算表达式。每次遇到运算符或者字符串的末尾时,根据前一个运算符来决定如何处理当前累积的数字。如果是加号或减号,将数字直接压入栈(减号则压入其负值)。对于乘号或除号,先从栈中弹出顶部数字,执行乘法或除法操作,然后将结果再压回栈中。最后,将栈中所有数字求和得到最终结果。这种方法有效地利用栈来处理运算符的优先级,避免了使用递归或额外的数据结构。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在处理表达式时,遇到运算符或字符串末尾才处理累积的数字的原因是什么?
▷🦆
为什么在处理乘除运算时,只从栈中弹出一个数字进行操作,而不是考虑连续的乘除运算如何处理?
▷🦆
在算法中,如何确保在处理除法时能够正确向下取整,尤其是在涉及负数时?
▷