package com.cubemonkey.stack;
/**
* 使用栈完成表达式的计算
* @author CubeMonkey
* @create 2020-06-04 18:41
*/
public class Calculator {
static int id;
/**
* 计算指定运算符
* @param num1 被操作数
* @param num2 操作数
* @param oper 运算符
* @return
*/
public static int calc(int num1, int num2, char oper){
int num = 0;
switch (oper){
case '+':
num = num1 + num2;
break;
case '-':
num = num1 - num2;
break;
case '*':
num = num1 * num2;
break;
case '/':
num = num1 / num2;
break;
default:
throw new RuntimeException("oper Error");
}
return num;
}
/**
* 判断指定字符是不是数字
* @param ch
* @return
*/
public static boolean isDigit(char ch){
return ch >= '0' && ch <= '9';
}
/**
* 中缀表达式的计算
*
*
* 计算思路
* 1.通过一个index值(索引) ,来遍历我们的表达式
* 2.如果我们发现是一个数字 就直接入数栈
* 3.如果发现扫描到是一个符号, 就分如下情况
* 3.1如果发现当前的符号栈为空,就直接入栈
* 3.2如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于核中
* 的操作符,就需要从数栈中pop出两个数在从符号栈中pop出-一个符号,进行运算,
* 将得到结果,入数栈,然后将当前的操作符入符号栈,如果当前的操作符的优先级大
* 于栈中的操作符,就直接入符号栈.
* 4.当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运行.
* 5.最后在数栈只有一个数字,就是表达式的结果
* @param exp
* @return
*/
public static int calculate(String exp){
LinkedStack<Character> operatorStack = new LinkedStack<>();
LinkedStack<Integer> numStack = new LinkedStack<>();
int index = 0;
int length = exp.length();
char ch;
while(index < length){
//优化?
ch = exp.charAt(index);
if(isDigit(ch)){//解决多位数问题
int num = ch-'0';
while(index + 1 < length && isDigit(exp.charAt(index+1))){
num = num*10 + exp.charAt(++index)-'0';
}
numStack.push(num);
}else{
char operator = ch;
switch (operator){
case '+':
case '-':
while(!operatorStack.isEmpty() && operatorStack.peek() != '(') {
char p = operatorStack.pop();
int num2 = numStack.pop();
int num1 = numStack.pop();
numStack.push(calc(num1, num2, p));
}
operatorStack.push(operator);
break;
case '*':
case '/':
while(!operatorStack.isEmpty() && operatorStack.peek() != '(' && (operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
char p = operatorStack.pop();
int num2 = numStack.pop();
int num1 = numStack.pop();
numStack.push(calc(num1, num2, p));
}
operatorStack.push(operator);
break;
case '(':
operatorStack.push(operator);
break;
case ')':
while(!operatorStack.isEmpty() && operatorStack.peek() != '(') {
char p = operatorStack.pop();
int num2 = numStack.pop();
int num1 = numStack.pop();
numStack.push(calc(num1, num2, p));
}
if(operatorStack.peek() == '('){
operatorStack.pop();
}
break;
default:
break;
}
}
index++ ;
}
while(!operatorStack.isEmpty()){
char p = operatorStack.pop();
int num2 = numStack.pop();
int num1 = numStack.pop();
numStack.push(calc(num1, num2, p));
}
int ans = numStack.pop();
return ans;
}
public static void main(String[] args) {
String exp = "7*2*(2-5)+1-5+3-4";
Calculator calculator = new Calculator();
id = 1;
System.out.println(exp + " = " + calculator.calculate(exp));
}
}
数据结构-中缀表达式的计算
最新推荐文章于 2023-05-29 09:32:26 发布