问题定义
请写一个能实现中缀表达式字符串的计算,支持加减乘除四种运算和小括号。
解决思路
1. 首先申请两个栈,一个数字栈stack1,一个符号栈stack2
2. 实现两个函数:第一个为当前操作符与指定符号优先级的比较,若优先级高于指定的
则返回true(指定符号若为小括号,只会为左括号,其优先级最低)
第二个实现指定操作符和操作数的运算
3. 将操作分为3类,第一类为遇到操作数,第二类为遇到符号数,第三类为遇到小括号
4. 遍历输入的中缀表达式字符串。
- 若遍历到的为操作数,为了防止该操作数为多位数,则需要往后探一位。
- 若后一位为操作数则暂不处理,与下一位一起处理,计算真正的操作数;若后一位不是操作数,则将计算的操作数放入stack1中。
- 若遍历到的为操作符,则需要判断stack2是否为空,为空则直接入栈;若栈不为空,则判断当前操作符的优先级是否高于栈顶元素的优先级,若高于,则直接入栈。若不高于,则弹出栈顶元素,并从stack1中弹出两个元素进行计算,并将结果入栈stack1,弹栈终止条件为:栈为空或元素优先级高于栈顶元素。
- 若遍历到的为小括号。若为左括号,则直接入栈;若为右括号,则弹出栈顶元素,并从stack1中弹出两个元素进行计算,并将结果入栈stack1,弹栈终止条件为:遇到左括号。条件终止后,将左括号从栈中删除
- 最后,若符号栈不为空,则弹出stack2栈顶元素,并从stack1中弹出两个元素进行计算,并将结果入栈stack1,弹栈终止条件为:stack2栈为空
- 最终的计算结果为栈1中的栈顶元素
代码部分
import java.util.*;
public class Solution {
public int solve (String s) {
// write code here
char[] chars = s.toCharArray();
int number=0;
int length = s.length();
int final_number = 0;
int left_number=0;
int rignt_number=0;
Stack<Integer> stack1 = new Stack<Integer>();
Stack<String> stack2 = new Stack<String>();
//遍历表达式
for (int i = 0; i < length; i++) {
char ele = chars[i];
//处理数据情况
if (Character.isDigit(ele)) {
number=number*10+ele-'0';
if(i+1<length&&Character.isDigit(chars[i+1])){
}
else{
stack1.push(number);
number=0;
}
}
//处理操作符
else if (ele == '+' || ele == '-' || ele == '*' || ele == '/') {
if(stack2.isEmpty()){
stack2.push(String.valueOf(ele));
}
else{
while(!stack2.isEmpty()&&!compareOperation(ele,stack2.peek())){
rignt_number=stack1.pop();
left_number=stack1.pop();
final_number=operation(left_number,rignt_number,stack2.pop());
stack1.push(final_number);
}
stack2.push(String.valueOf(ele));
}
}
else{
//处理括号
if(ele=='('){
stack2.push(String.valueOf(ele));
}
else{
while(!stack2.isEmpty()&&!stack2.peek().equals("(")){
rignt_number=stack1.pop();
left_number=stack1.pop();
final_number=operation(left_number,rignt_number,stack2.pop());
stack1.push(final_number);
}
stack2.pop();
}
}
}
while(!stack2.isEmpty()){
rignt_number=stack1.pop();
left_number=stack1.pop();
final_number=operation(left_number,rignt_number,stack2.pop());
stack1.push(final_number);
}
return stack1.pop();
}
//比较遍历到的字符与栈顶字符的优先级
public static boolean compareOperation(char cur, String peek) {
if (cur == '*' || cur == '/') {
if (peek .equals("*") || peek .equals("/")) {
return false;
} else {
return true;
}
} else if (cur == '+' || cur == '-') {
if (peek .equals("*")|| peek .equals("/")|| peek .equals("+")|| peek .equals("-")) {
return false;
} else {
return true;
}
}
return true;
}
public static int operation(int left_number,int right_number,String operation){
if(operation.equals("+")){
return left_number+right_number;
}
else if (operation.equals("-")){
return left_number-right_number;
} else if (operation.equals("/")) {
return left_number/right_number;
}
else {
return left_number*right_number;
}
}
}