给出一个包含有四则运算的字符串(含括号),计算结果
- 预处理 ```java // 计算式有可能包含空格,单目运算符等, // 这些都需要我们进行预处理(放在遍历的代码处理也行)
// 利用replace()去除空格 str1 = “1 + 2”; str1 = str1.replace(“ “, “”); //结果为: str1 = “1+2”
// 利用 replace() 对单目运算符进行处理,添加0使其变为双目运算符 // 例如(-1+2) -> (0-1+2) str2 = “(-1+2)”; str2 = str2.replace(“(-“, “(0-“); str2 = str2.replace(“(+”, “(0+”);
2. 利用两个栈进行对字符串的解析(边遍历边计算),其中 nums 用于存储所有参与运算的数字,ops 存储运算符和括号。```javaDeque<Integer> nums = new ArrayDeque<>();Deque<Character> ops = new ArrayDeque<>();// 防止第一个数为负数,先往nums 加个 0nums.addLast(0);// 附加:定义符号运算的优先级Map<Character, Integer> map = new HashMap<Character, Integer>() {{put('-', 1);put('+', 1);put('*', 2);put('/', 2);put('%', 2);put('^', 3);}};
- 对计算式进行遍历 ```java //char ch = s.charAt(i); 当前遍历的字符
if(ch == ‘(‘){
// 直接进入符号栈ops
}
else if(ch == ‘)’){
// 对ops执行出栈操作,循环出口:(遇到一个左括号’(‘为止 或者 ops为空)
// 且每次出栈得到一个操作符,需要从nums中取出两个操作数,进行运算,
// 再把运算结果放入nums中
while(!ops.isEmpty()) {
// 此处运算符不出栈的原因是 在执行calc()时会将当前运算符出栈
char op = ops.peekLast();
if(op != ‘(‘){
calc()
}else{
//循环出口
// 记得将ops中的’(‘出栈
ops.pollLast();
break;
}
}
}
// 非空格字符
else{
if(ch 为 数字) {
//因为可能由多位数字字符组成一个数值,所以需要一个循环取到一个完整的数值
//然后将该数值进栈(nums)
}else{
// 运算符
// 如果 ops 中的运算符的优先级大于或等于待入栈的运算符(ch),
// 则需要先对 ops 执行出栈操作
// 循环结束标志: ops为空 || 遇到左括号’(‘ || ch的优先级高于当前栈顶的运算符
// 此时,将运算符入栈
}
}
// 有可能遍历完计算式后,还没有完成计算 // 需要检查 ops,若非空,则进行计算 while(!ops.isEmpty()){ calc(); }
// nums 的栈顶元素则为最终计算的结果
```
