package com.cai.math;
import java.util.Stack;
/**
* 目标:java实现直接算出中缀表达式:例:3+2*5-6的值
* 思路:1.分别把数字,和符号放入两个栈中
* 2.如果是数字:直接入数字栈
* 3.如果是符号,当前符号的优先级别小于等于上一个符号,数字栈pop两个值,符号栈pop出一个符号运算,值放入数字栈,当前符号入符号栈
* 当前符号的优先级大于上一个符号,符号直接入符号栈
* 4.一次取出数字栈的值,符号栈的符号,依次运算,值入数字栈
* 5.知道数字栈中只有一个值(或者符号栈为空)结束,取出数字栈的当前值为最终结果
*/
public class ExpressionTest {
public static void main(String[] args) {
String expression = "13+2*5-6"; //这里给正确的表达式,先不做检验表达式正确与否
Stack<String> operateStack = new Stack<String>();//操作法栈
Stack<Integer> numStack = new Stack<Integer>();//数字栈
//开始取表达式
String currentChar = "";
for (int i = 0; i < expression.length(); i++) {
String index = expression.substring(i,i+1);
boolean flag = isNum(index);
if(flag){
boolean lastNum = isNum(currentChar);
if(lastNum&&!numStack.empty()){
Integer lastValue = numStack.pop();
index = String.valueOf(lastValue)+index;
}
numStack.push(Integer.valueOf(index));
}else{
if(!operateStack.empty()){
int thisOperate = priorityLevel(index);
int lastOperate = priorityLevel(operateStack.peek());
if(thisOperate<=lastOperate){
Integer num1 = numStack.pop();
Integer num2 = numStack.pop();
String operate = operateStack.pop();
Integer thisResult = getResult(operate,num1,num2);
numStack.push(thisResult);
}
}
operateStack.push(index);
}
currentChar = index;
}
while (!operateStack.empty()){
Integer num1 = numStack.pop();
Integer num2 = numStack.pop();
String operate = operateStack.pop();
Integer thisResult = getResult(operate,num1,num2);
numStack.push(thisResult);
}
System.out.println(expression+"="+numStack.pop());
}
/**
*
* @param operate 运算符
* @param num1 第一个pop的数字
* @param num2 第二个pop的数字
* @return 运算结果
*/
public static Integer getResult(String operate,Integer num1,Integer num2){
Integer result = 0;
if("+".equals(operate)){
result=num2+num1;
}else if("-".equals(operate)){
result=num2-num1;
}else if("*".equals(operate)){
result=num2*num1;
}else if("/".equals(operate)){
result=num2/num1;
}
return result;
}
/**
* @param operate 操作符
* @return 优先级别(暂时只支持‘+,-,*,/’),数值越大,优先级别越高
*/
public static int priorityLevel(String operate){
int result = -1;
if("+".equals(operate)||"-".equals(operate)) result=0;
else if("*".equals(operate)||"/".equals(operate)) result=1;
else result=-1;
return result;
}
/**
* 判断当前字符是否是数字 是 true 否 false
* @param chart 当前字符
* @return
*/
public static boolean isNum(String chart){
if("+".equals(chart)||"-".equals(chart)||"*".equals(chart)||"/".equals(chart)) return false;
return true;
}
}