中缀表达式转后缀表达式思路及实现

中缀表达式转后缀表达式思路及实现

中缀表达式即人们平常所见的表达式,如我们数学里学的四则运算;
后缀表达式即计算机能正常识别的表达式;
以下是实现中缀转后缀的思路;
1、初始化两个栈,存放数据和数字
2、从左至右扫描表达式
3、遇到的是数字直接压入数字栈中
4、遇到符号时需分如下情况:
a、当该符号是第一个符号时直接压入
b、后续的符号需和栈顶的符号比较优先级,如果当前符号优先级高于栈顶符号,则直接压入,反之则将栈顶符号弹出压入数字栈,当前的符号压入符号栈
c、如符号是(则直接压入符号栈,如符号是)则需将符号栈中(之前的所有符号全部弹出压入数字栈中,最后弹出(并不存)符号;
5、最后如果符号栈中不为空,则全部弹出压入数字栈中
6、反向输出数字栈的元素即为后缀表达式
此处的数字栈可以用集合或字符串代替就不用反向输出了,直接正序输出即可。
代码方面做了一些简单的处理对于空格和数字有一些简单判断,但是还没有考虑到负数和中括号和大括号问题,其中中括号和大括号问题类似于小括号的处理思路,但是负数还需要特殊处理,暂时没有思考!!!

package com.arrayStack;

import io.micrometer.core.instrument.util.StringUtils;

import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PostfixExpression {
    /**
     * 中缀表达式:人类正常看懂的表达式即为中缀表达式
     * 后缀表达式:计算机看懂的表达式
     * 中缀表达式转换后缀表达式
     * a + b * c + ( d * e + f ) * g转换为后缀表达式
     */
    private static String createPostfixExpression(String expression) {
        StringBuilder postfixExpression = new StringBuilder();
        Stack stack = new Stack();
        //先对表达式做处理
        String s = replaceAllBlank(expression);
        String exp = addBlank(s);
        String[] sp = exp.split(" ");
        //遍历处理每个元素判断处理
        for (String str:sp
        ) {
            //判断是不是数字
            boolean checkNo = checkNo(str);
            if (checkNo){
                //如果是数字直接放在返回结果的后缀表达式中
                postfixExpression.append(str);
                postfixExpression.append(",");
            }else if ("+".equals(str)||"-".equals(str)||"*".equals(str)||"/".equals(str)||"(".equals(str)||")".equals(str)){
                //如果栈内为空直接加入
                if (stack.isEmpty()){
                    stack.push(str);
                    continue;
                }
                //如果是(符号也直接加入
                if ("(".equals(str)){
                    stack.push(str);
                    continue;
                }
                if (")".equals(str)){

                    while (!stack.isEmpty()){
                        if ("(".equals(stack.peek())){
                            stack.pop();
                            break;
                        }
                        postfixExpression.append(stack.pop());
                        postfixExpression.append(",");
                    }
                }else {
                    //判断当前符号和栈顶符号的优先级,如果大于则直接加入栈中,反之则取出栈顶符号输出到后缀表达式的返回结果中
                    while (true){
                        if (!stack.isEmpty()&&checkPriority(str)>checkPriority((String)stack.peek())){
                            stack.push(str);
                            break;
                        }else if (!stack.isEmpty()){
                            postfixExpression.append(stack.pop());
                            postfixExpression.append(",");
                        }else {
                            stack.push(str);
                            break;
                        }
                    }
                }
            }else {
                //其他的符号暂时不考虑处理
                throw new RuntimeException("输入的符号错误");
            }
        }//52-112=-60
        //处理完每个元素后,如果栈中还有符号,则遍历出来追加在后缀表达式中
        while (true){
            if (stack.isEmpty()){
                break;
            }
            postfixExpression.append(stack.pop());
            postfixExpression.append(",");
        }
        return postfixExpression.toString().substring(0,postfixExpression.toString().length()-1);
    }
    //判断优先级如果是*或/返回1 +或—返回0值大者优先
    private static int checkPriority(String str){
        if ("*".equals(str)||"/".equals(str)){
            return 1;
        }else if ("+".equals(str)||"-".equals(str)){
            return 0;
        }else {
            return -1;
        }
    }
    //去除所有空格
    public static String replaceAllBlank(String str) {
        String s = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            /**
             * \n 回车(\u000a)
             * \t 水平制表符(\u0009)
             * \s 空格(\u0008)
             * \r 换行(\u000d)
             */
            Matcher m = p.matcher(str);
            s = m.replaceAll("");
        }
        return s;
    }
    //给中缀表达式的每个符号两边加一个空格,以便分割处理
    private static String addBlank(String str){
        if (StringUtils.isEmpty(str)){
            return str;
        }
        if (str.contains("+")){
            str = str.replace("+"," + ");
        }
        if (str.contains("-")){
            str = str.replace("-"," - ");
        }
        if (str.contains("*")){
            str = str.replace("*"," * ");
        }
        if (str.contains("/")){
            str = str.replace("/"," / ");
        }
        if (str.contains("(")){
            str = str.replace("("," ( ");
        }
        if (str.contains(")")){
            str = str.replace(")"," ) ");
        }
        str = str.replace("  "," ").trim();
        return str;
    }
    //判断是不是数字
    private static boolean checkNo(String str){
        String pre = "^[0-9]*[1-9][0-9]*$";
        boolean b = Pattern.matches(pre, str);
        return b;
    }
    public static void main(String[] args) {
        String postfixExpression = createPostfixExpression("30 + 11 * 2 - ( 3 * 4 + 5 ) * 6");
        System.out.println(postfixExpression);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值