前、中、后缀表达式【待完成】

  这里所谓的前缀,中缀,后缀是根据操作符的位置来定的,如果操作符在操作数前面,则称为前缀表达式,例如“- + 1 × + 2 3 4 5”;如果操作符在操作数之间,则称为中缀表达式,例如

“1+((2+3)×4)-5”;如果操作符在操作数后面,则称为后缀表达式,例如“1 2 3 + 4 × + 5 -”。

  虽然中缀表达式符合人类的日常思维习惯,但是计算机在存储中缀表达式时,需要使用树这种数据结构,如果表达式过于复杂,那么树的高度会变得很高,大大增加了时间复杂度和空间复杂度。如果转换成线性结构,那么效率将变得高很多,所以需要将中缀表达式先转换成前缀或者后缀表达式,然后依靠栈这种线性数据结构来进行计算。

  前缀表达式又叫波兰表达式,后缀表达式又叫逆波兰表达式。前缀表达式基本没有在商业计算机中使用过,所以现实中用的更多的是后缀表达式。

1,前缀表达式

 

2,中缀表达式

 

2.1 中缀表达式转后缀表达式

  中缀表达式为:1+(2-3)*4+4/2

  对应后缀表达式为:1 2 3 - 4* + 4 2 / +

  如何将一个中缀表达式转化为后缀表达式?我们需要借助栈的力量,用它来存放运算符。算法流程如下:

  首先将各种运算符(包括括号)的优先级排列如下(数字越大,优先级越高):

    1:(

    2:+ -

    3:* /

    4:)

对输入的中缀表达式从左到右遍历:

  1)如果遇到数字,直接添加到后缀表达式末尾;

  2)如果遇到运算符+、-、*、/:

    先判断栈是否为空。若是,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。若栈顶元素优先级大于或等于此操作符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,并继续进行上述判断。如果不满足上述判断或者栈为空,将这个运算符入栈。要注意的是,经过上述步骤,这个运算符最终一定会入栈。

  3)如果遇到括号:

    如果是左括号,直接入栈。如果是右括号,弹出栈中第一个左括号前所有的操作符,并将左括号弹出。(右括号别入栈)。

  4)字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。

 

 

2.2 中缀表达式直接计算

 

3,后缀表达式【很简单,一个Stack解决问题】

  也称为逆波兰表达式

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 -
 */

 

posted on 2019-09-17 22:28  周健康  阅读(272)  评论(0编辑  收藏  举报

导航