这里所谓的前缀,中缀,后缀是根据操做符的位置来定的,若是操做符在操做数前面,则称为前缀表达式,例如“- + 1 × + 2 3 4 5”;若是操做符在操做数之间,则称为中缀表达式,例如java
“1+((2+3)×4)-5”;若是操做符在操做数后面,则称为后缀表达式,例如“1 2 3 + 4 × + 5 -”。算法
虽然中缀表达式符合人类的平常思惟习惯,可是计算机在存储中缀表达式时,须要使用树这种数据结构,若是表达式过于复杂,那么树的高度会变得很高,大大增长了时间复杂度和空间复杂度。若是转换成线性结构,那么效率将变得高不少,因此须要将中缀表达式先转换成前缀或者后缀表达式,而后依靠栈这种线性数据结构来进行计算。数据结构
前缀表达式又叫波兰表达式,后缀表达式又叫逆波兰表达式。前缀表达式基本没有在商业计算机中使用过,因此现实中用的更多的是后缀表达式。spa
中缀表达式为:1+(2-3)*4+4/2code
对应后缀表达式为:1 2 3 - 4* + 4 2 / +blog
如何将一个中缀表达式转化为后缀表达式?咱们须要借助栈的力量,用它来存放运算符。算法流程以下:字符串
首先将各类运算符(包括括号)的优先级排列以下(数字越大,优先级越高):it
1:(io
2:+ -ast
3:* /
4:)
对输入的中缀表达式从左到右遍历:
1)若是遇到数字,直接添加到后缀表达式末尾;
2)若是遇到运算符+、-、*、/:
先判断栈是否为空。如果,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。若栈顶元素优先级大于或等于此操做符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,并继续进行上述判断。若是不知足上述判断或者栈为空,将这个运算符入栈。要注意的是,通过上述步骤,这个运算符最终必定会入栈。
3)若是遇到括号:
若是是左括号,直接入栈。若是是右括号,弹出栈中第一个左括号前全部的操做符,并将左括号弹出。(右括号别入栈)。
4)字符串遍历结束后,若是栈不为空,则弹出栈中全部元素,将它们添加到后缀表达式的末尾,直到栈为空。
也称为逆波兰表达式
package com.cnblogs.mufasa.Main_last; import org.junit.Test; import java.util.Scanner; import java.util.Stack; public class Main { public static void Solution(String str){ Stack<Float> stack=new Stack<>(); String[] strs=str.split(" "); for(int i=0;i<strs.length;i++){ if(strs[i].matches("([0-9]+)\\.?([0-9]*)")){//是一个数字,多是多位的 stack.add(Float.valueOf(strs[i])); }else { float num1=stack.pop(); float num2=stack.pop(); stack.add(dealCalcu(num1,num2,strs[i])); } } System.out.print(stack.pop()); } private static float dealCalcu(float num1,float num2,String str){ switch (str){ case "+":return num1+num2; case "-":return num1-num2; case "*":return num1*num2; case "×":return num1*num2; case "X":return num1*num2; case "/":return num1/num2; default:throw new UnsupportedOperationException("非法运算符"); } } @Test public void LastCalcu (){ String str="1.11 2 3 + 4 * + 5 -"; Solution(str); } public static void main(String[] args) { Scanner sc=new Scanner(System.in); Solution(sc.nextLine()); } } /* 1 2 3 + 4 * + 5 - */