这一题是栈的应用,思路就是使用双栈的去记录数据。
栈1:记录数字。
栈2:记录操作符。
思路就是一次遍历,遍历的同事枚举每一个字符。需要一个hash表记录字符的优先级。
可能出现4种情况:
1.括号 "(" , 直接入栈,然后遍历下一个数。
2.括号 “)”, 需要把栈里面的数拿出来,进行计算,一直到匹配到一个字符为“(”为止。
3.如果是一个数字,需要考虑这个数字是不是一个多位数字,就是比如 1, 11, 111这种数 字,因 为遍历的是字符,所以需要把它加起来。
4,。就是剩余的情况了,就是操作字符,直接计算就行了。
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/**
* @author xnl
* @Description:
* @date: 2022/5/23 21:06
*/
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
// String str = "1+2";
String str = "(2*(3-4))*5";
//String str = "3+2*3*4-1";
System.out.println(solution.solve(str));
}
// 存储字符优先级
Map<Character, Integer> charTable = new HashMap<Character, Integer>(3){{
put('+', 1);
put('-', 1);
put('*', 2);
}};
public int solve (String s) {
s = s.replaceAll(" ", ""); // 去掉多余的空格
char[] chars = s.toCharArray();
Stack<Integer> numStack = new Stack<>(); // 数字栈
numStack.push(0); // 避免第一个数是负数的情况
Stack<Character> characterStack = new Stack<>();// 字符栈
for (int i = 0; i < chars.length; ){
// 如果当前字符是括号
if (chars[i] == '('){
characterStack.push(chars[i++]);
continue;
}
// 如果是结尾括号
if (chars[i] == ')'){
while (!characterStack.isEmpty() && characterStack.peek() != '(' ){
calculation(numStack, characterStack);
}
characterStack.pop();
i++;
continue;
}
// 如果是0-9的数字,可能是二位数或者三位数以此类推
if (chars[i] >= '0' && chars[i] <= '9'){
int temp = 0;
while (i < chars.length && chars[i] >= '0' && chars[i] <= '9'){
temp = temp * 10 + (chars[i++] - '0');
}
numStack.push(temp);
} else {
if (!characterStack.isEmpty() && (chars[i] == '+' || chars[i] == '-' || chars[i] == '*')){
// 每次判断上一个字符和当前字符的优先级,优先级低或者相等的才可以被执行
if (characterStack.peek() != '(' &&charTable.get(chars[i]) <= charTable.get(characterStack.peek())) {
calculation(numStack, characterStack);
}
}
characterStack.push(chars[i++]);
}
}
// 把多余栈的数据给他清一下
while (!characterStack.isEmpty()){
calculation(numStack, characterStack);
}
return numStack.peek();
}
/**
* 计算栈内数据的方法,,是一个计算器
* @param nums
* @param characters
*/
private void calculation(Stack<Integer> nums, Stack<Character> characters) {
if (nums.isEmpty() || characters.isEmpty()) {
return;
}
Integer num1 = nums.pop();
Integer num2 = nums.pop();
Character c = characters.pop();
if (c == '+') {
nums.push(num1 + num2);
} else if (c == '-') {
nums.push(num2 - num1);
} else if (c == '*') {
nums.push(num1 * num2);
}
}
}