1.计算器问题
对应leetcode227. 基本计算器 II - 力扣(LeetCode)](leetcode.cn/problems/ba…)
解题思路:
就拿 s = "3+2*2" 这个例子来说:首先我们应该要明确的是即使+ - 运算符出现在字符串的前面,但如果存在 *,/ 运算时,乘除运算一定要优先进行;这才是符合正常的数学表达式的运算逻辑;那么我们应该怎么处理才能做到这一点呢?
数据结构栈就可以实现该效果,如果我们把 ' * ' 号前面的所有数字全部依次入栈,此时栈顶元素为 2 ,那么当字符串遍历到第二个2时,只要和当前栈顶元素相乘再共同入栈,保证最后只要正常累加栈中元素即可实现计算器的效果;
画个图来解释效果更佳:
初始过程:preSign用来记录当前遍历到的字符的前一个运算符是哪个,默认为' + ';
num 用来记录需要入栈的数值;
stack 初始为空栈;
中间过程:当 i >=0 && i<=charArr.length-1时
当 i 来到数组最后一个位置时
代码如下:
public static int calculate(String str) {
Stack<Integer> stack = new Stack<>();
char[] charArr = str.toCharArray();
// 记录上一个符号 ,初始化为'+';
char preSign = '+';
int num = 0; //定义存入栈中的各个整数
for (int i = 0; i < charArr.length; i++) {
if (Character.isDigit(charArr[i])) {
// 如果字符串是 "5+105",如果遍历到"105" 位置时,能让105整体入栈
num = num * 10 + charArr[i] - '0';
}
if (!Character.isDigit(charArr[i]) && charArr[i] != ' ' || i == charArr.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);
}
// 将当前运算符赋值给preSign;这样当又来到一个新的位置时,保证preSign一直记录的时新位置的前一个
preSign = charArr[i];
// 要将num重新赋值为0,防止重复计算
num = 0;
}
}
// 定义返回的结果
int sum = 0;
// 累加栈中的元素,即可得到返回结果
while (!stack.isEmpty()) {
sum += stack.pop();
}
return sum;
}
总的来说这道题目如果要完全通过的话还是要花很多功夫的;需要考虑的点还是很多的,比如说1. 遍历到最后一个位置时,同样需要进行入栈操作;2. 运算符为 +,- 时,该怎么进行入栈操作,运算符为 * , / 时,又该怎么进行入栈操作; 3. num = num * 10 + charArr[i] - '0'这一行代码该怎么理解等等;