中缀表达式变后缀表达式

中缀表达式变为后缀表达式 如图所示~~
在这里插入图片描述

那么用栈怎么来表示呢???
看图啦!!!
第一步:遇到数字直接放到后缀表达式
在这里插入图片描述

第二步:优先级高的入栈
第三步:每次入栈之前和栈顶运算符进行优先级比较,如果栈内高于栈外,那么出栈一次
第四步:如果是相同优先级的两个运算符,规定栈内高于栈外
在这里插入图片描述

第五步:栈外的左括号优先级最高。入栈之后,优先级变为最低
在这里插入图片描述

第六步:栈外的右括号,优先级最低,低到和栈内左括号一样
在这里插入图片描述

注意哦~~后缀表达式没有括号的啦

先定义运算符常量

package constant;

/**
 * Description:运算符常量
 * author:SS
 * Date: 2018/12/4  19:01
 * packageName: constant
 */

public class Constant {
    //数字越小优先级越高
    public static final int OPERATORS_PRIO_PLUS_IN = 4;  //栈内加法
    public static final int OPERATORS_PRIO_SUB_IN  =  4;   //栈内减法
    public static final int  OPERATORS_PRIO_MULTY_IN  =  2; //栈内乘法
    public static final int OPERATORS_PRIO_DIV_IN  =  2 ;  //栈内除法
    public static final int OPERATORS_PRIO_LEFT_BRAK_IN  =  10;  //栈内左括号

    public static final int OPERATORS_PRIO_PLUS_OUT  =  5 ; //栈外加法
    public static final int OPERATORS_PRIO_SUB_OUT  =   5;   //栈外减法
    public static final int OPERATORS_PRIO_MULTY_OUT  =  3; //栈外乘法
    public static final int OPERATORS_PRIO_DIV_OUT  =  3;   //栈外除法
    public static final int OPERATORS_PRIO_LEFT_BRAK_OUT =  1;  //栈外左括号
    public static final int OPERATORS_PRIO_RIGHT_BRAK_OUT =  10;  //栈外右括号
    public static final int OPERATORS_PRIO_ERROR = -1;
}

功能代码

package dao;

import constant.Constant;

/**
 * Description:
 * author:SS
 * Date: 2018/12/5  14:52
 * packageName: dao
 */
public class TestDemoML {
    /**
     * 得到当前运算符的优先级
     * @param opera
     * @param instack
     * @return
     */
    public int getPrio(char opera,boolean instack){
        int prio = Constant.OPERATORS_PRIO_ERROR;
        if (instack){
            switch (opera){
                case '+':
                    prio = Constant.OPERATORS_PRIO_PLUS_IN;
                    break;
                case '-':
                    prio = Constant.OPERATORS_PRIO_SUB_IN;
                    break;
                case '*':
                    prio = Constant.OPERATORS_PRIO_MULTY_IN;
                    break;
                case '/':
                    prio = Constant.OPERATORS_PRIO_DIV_IN;
                    break;
                case '(':
                    prio = Constant.OPERATORS_PRIO_LEFT_BRAK_IN;
                    break;
                default:
                    prio = Constant.OPERATORS_PRIO_ERROR;
                    break;
            }
        }
        else {
            switch (opera){
                case '+':
                    prio = Constant.OPERATORS_PRIO_PLUS_OUT;
                    break;
                case '-':
                    prio = Constant.OPERATORS_PRIO_SUB_OUT;
                    break;
                case '*':
                    prio = Constant.OPERATORS_PRIO_MULTY_OUT;
                    break;
                case '/':
                    prio = Constant.OPERATORS_PRIO_DIV_OUT;
                    break;
                case '(':
                    prio = Constant.OPERATORS_PRIO_LEFT_BRAK_OUT;
                    break;
                case ')':
                    prio = Constant.OPERATORS_PRIO_RIGHT_BRAK_OUT;
                    break;
                default:
                    prio = Constant.OPERATORS_PRIO_ERROR;
                    break;
            }
        }
        return prio;
    }

    //将中缀表达式转换为后缀表达式的过程
    public void strMidToLast(String strMid,char[] strLast){
        char[] stack = new char[strMid.length()]; //存放运算符
        int top = 0; //栈的下标
        int i = 0; //中缀表达式的下标
        int j = 0; //后缀表达式的下标
        int prio_in = -1; //当前栈内的运算符的优先级
        int prio_out = -1;//当前栈外的运算符的优先级

        while (i != strMid.length()){
            if (Character.isDigit(strMid.charAt(i))){ //判断是否为数字字符
                strLast[j] = strMid.charAt(i); //是数字的话直接放进后缀表达式
                i++;
                j++;
            }else { //当为运算符时
                if (top == 0){ //栈为空的时候
                    stack[top++] = strMid.charAt(i); //直接将运算符入栈
                    i++;
                }else { //栈里有运算符时
                    prio_in = getPrio(stack[top-1],true); //获取栈内的栈顶运算符
                    prio_out = getPrio(strMid.charAt(i),false); //获取栈外的运算符
                    if (prio_out < prio_in){ //如果栈外的优先级高于栈内的
                        stack[top++] = strMid.charAt(i); //入栈
                        i++;
                    }else if (prio_out == prio_in){
                        top--;
                        i++;
                    }else { //栈内优先级高于栈外
                        strLast[j++] = stack[top-1]; //出栈
                        top--;
                    }
                }
            }
        }
        while (top > 0){
            strLast[j++] = stack[--top];
        }
    }

    //计算后缀表达式的结果
    /**
     *取栈顶运算符和栈顶两个数字进行计算
     *计算的结果再入栈,然后再计算
     * @param strLast
     * @return
     */
    public int arithmetic(char[] strLast){
        int[] stack = new int[strLast.length];
        int top = 0;
        int i = 0; //strLast的下标
        int result = 0; //存放运算的结果
        int num1 = 0;
        int num2 = 0;

        while (i != strLast.length){
            if (Character.isDigit(strLast[i])){ //是数字时
                //将数字字符转换为int
                String str1 = Character.toString(strLast[i]);
                stack[top++] = Integer.parseInt(str1);
            }else if (strLast[i] == ' '|| strLast[i] == '\u0000'){ //为空字符或默认值时

            }else { //是运算符时
                num1 = stack[--top]; //右操作数
                num2 = stack[--top]; //左操作数
                char opera = strLast[i];
                result = getResult(opera,num2,num1);
                stack[top++] = result;
            }
            i++;
        }
        return result;
    }

    public int getResult(char opera,int left,int right) {
        switch (opera) {
            case '+':
                return left + right;
            case '-':
                return left - right;
            case '*':
                return left * right;
            case '/':
                return left / right;
        }
        return -1;
    }

}

测试代码

package main;

import dao.TestDemoML;

import java.util.Arrays;

/**
 * Description:
 * author:SS
 * Date: 2018/12/4  19:23
 * packageName: main
 */
public class Test {
    public static void main(String[] args) {
        TestDemoML testDemoML = new TestDemoML();
        String strMid = "2+3*5-4*(5-3)";
        char[] strLast = new char[strMid.length()];
        testDemoML.strMidToLast(strMid,strLast);
        System.out.println(Arrays.toString(strLast));
        int result = testDemoML.arithmetic(strLast);
        System.out.println(result);
    }
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值