中缀表达式转后缀表达式

从前面栈实现综合计算器(中缀表达式)逆波兰(后缀表达式)计算器两节中可以看出,后缀表达式适合计算机进行计算,但是写法复杂,难以看懂,中缀表达式适合人类读懂,但是不适合计算机进行计算,那么我们就需要搭桥,让中缀表达式转成后缀表达式,以方便计算机计算。

- 中缀表达式转换为后缀表达式步骤:
    初始化两个栈 S1(存储运算符)和S2(存储结果)
    从左到右遍历中缀表达式:	
    		若取出的字符是操作数:将操作数压入S2;
    		若取出的字符是运算符:
    		                  若S1为空栈: 取出的字符入S1栈;
    		                  若S1栈顶运算符是左括号:取出的字符入S1栈;
    		                  若取出的字符运算符比S1栈顶的运算符优先级高:取出的字符入S1栈;
    		                  否则将S1栈顶的运算符弹出并压入S2中;
    	   若取出的字符是括号:
    	                     若取出的字符是左括号,直接入S1栈;
    	                     若取出的字符是 右括号,则依次弹出S1栈的运算符,并压入S2,直到遇到左括号为止,此时一对括号丢弃;
    直到表达式遍历完毕,则将S1中剩余的运算符依次弹出并压入S2,
    最终S2中逆序输出的为后缀表达式。

在这里插入图片描述

举例 中缀表达式转后缀表达式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举例 代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 逆波兰表达式计算器
 */
public class PolandNotation {

    public static void main(String[] args) {
        
        List<String> infixExpression = toInfixExpressionList("1+((2+3)*4)-5");
        System.out.println("中缀表达式 : "+infixExpression);
        List<String> parseSuffixExpression = parseSuffixExpressionList(infixExpression);
        System.out.println("后缀表达式 : "+parseSuffixExpression);
        int result = calculate(parseSuffixExpression);
        System.out.println("计算结果为:"+result);

    }

    /**
     *  将表达式转化为中缀表达式
     * @param expression  表达式
     * @return
     */
    public static List<String> toInfixExpressionList(String expression){
        List<String>  list = new ArrayList<String>();
        int index = 0;
        while(index < expression.length()){
            char ch = expression.charAt(index);
            if((ch < 48) || (ch > 57)){//当前字符非数字
                list.add(ch+"");
                index++;
            }else{//当前字符是数字
                String str = "";
                //查看当前字符下一位是不是数字
                while (index<expression.length() && expression.charAt(index) >= 48 && expression.charAt(index) <= 57){
                    str += ch;
                    index++;
                }
                list.add(str);
            }
        }
        return list;
    }

    /**
     * 将中缀表达式转化为后缀表达式
     * @param list
     * @return
     */
    public static List<String> parseSuffixExpressionList(List<String> list){
        Stack<String> stack1 = new Stack<>();
        Stack<String> stack2 = new Stack<>();
        for (String item : list){
            if (item.matches("\\d+")){//数字
                stack2.push(item);
            }else if(item.equals("(")){//左括号
                stack1.push(item);
            }else if(item.equals(")")){//右括号
                //右括号,则依次弹出S1栈的运算符,并压入S2,直到遇到左括号位置,此时一对括号丢弃
                while (!stack1.peek().equals("(")){
                    stack2.push(stack1.pop());
                }
                stack1.pop();
            }else{//当前字符为运算符
                while (!stack1.empty() &&  operationPriority(stack1.peek()) >= operationPriority(item)){
                    stack2.push(stack1.pop());
                }
                stack1.push(item);
            }
        }
        while (!stack1.empty()){
            stack2.push(stack1.pop());
        }
        return stack2;
    }
    
    /**
     * 完成后缀表达式的计算
     * @param list
     * @return
     */
    public static int calculate(List<String> list){
        //创建栈 用于存放数据
        Stack<String> stack = new Stack<String>();
        //对存入后缀表达式的ArrayList进行遍历
        for (String item : list){
            //如果是数字 则入栈
            if(item.matches("\\d+")){//匹配数字
                stack.push(item);//入栈
            }else {//如果不是数字 则出栈两个数字 和当前符号进行计算  将计算结果入栈
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int sum = 0;
                if (item.equals("+")){
                    sum = num2 + num1;
                }
                if (item.equals("-")){
                    sum = num2 - num1;
                }
                if (item.equals("*")){
                    sum = num2 * num1;
                }
                if (item.equals("/")){
                    sum = num2 / num1;
                }
                stack.push(sum+"");
            }
        }
        //栈中剩余的最后一个数组则为计算结果
        return Integer.parseInt(stack.pop());
    }


    /**
     * 操作符的优先级
     * @param operation  true 表示乘除
     * @return
     */
    public static int operationPriority(String operation){
        int result = 0;
        switch (operation) {
            case "+":
                result = 1;
                break;
            case "-":
                result = 1;
                break;
            case "*":
                result = 2;
                break;
            case "/":
                result = 2;
                break;
            default:
                //System.out.println("不存在该运算符" + operation);
                break;
        }
        return result;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值