中缀表达式转前缀和后缀表达式-栈结构

前缀、中缀、后缀表达式

  • 前缀表达式:/+A*BCD。
  • 中缀表达式:A+B*C/D。
  • 后缀表达式:ABC*+D/。

中缀表达式转换后缀表达式思路

     操作数顺序不变,将运算符进行排序

  1. 将栈初始化为空栈;
  2. 从左到右扫描表达式的每一个字符,执行下面操作:

    2.1  遇到操作数:直接输出(添加到后缀表达式中)

    2.2  栈为空时,遇到运算符,直接入栈

    2.3  遇到左括号:将其入栈

    2.4  遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。

    2.5  遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈

    2.6  最终将栈中的元素依次出栈,输出。

中缀转前缀表达式思路

基本同以上相同,不同点:

1、上面的从左到右扫描表达式,改成从右向左扫描每一个字符。

2、左括号和右括号的判断和上面相反。

代码演示:

package com.arithmetic.learn.arith4.c1.chapter3;

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

public class C1_3_10 {

    public static void main(String[] args) {

        String e = "20+5*(15-(9+1))/2";
        String resultPost = "20 5 15 9 1 + - * 2 / +";
        List<String> postFix = convert2Postfix(e);
        System.out.println(postFix);
        List<String> prefix = convert2Prefix(e);
        String resultPre = "+ 20 / * 5 - 15 + 9 1 2";
        System.out.println(resultPre);
    }

    private static List<String> convert2Prefix(String e) {
        List<String> items = convertStrToItems(e);
        List<String> prefix = convertToPrefix(items);
        return prefix;
    }

    private static List<String> convertToPrefix(List<String> items) {
        List<String> prefix = new ArrayList<>();

        Stack<String> stack = new Stack();
        for(int i = items.size()-1; i>= 0; i--){
            operate(items.get(i),stack,prefix);
        }
        while(!stack.isEmpty()){
            prefix.add(stack.pop());
        }
        return prefix;
    }

    private static List<String> convert2Postfix(String e) {
        List<String> items = convertStrToItems(e);
        List<String> posfix = convertToPostfix(items);
        return posfix;
    }

    private static List<String> convertToPostfix(List<String> items) {
        List<String> postfix = new ArrayList<>();

        Stack<String> stack = new Stack();
        for(String item : items){
            operate(item,stack,postfix);
        }
        while(!stack.isEmpty()){
            postfix.add(stack.pop());
        }
        return postfix;
    }

    private static void operate(String item,Stack<String> stack, List<String> postfix) {
        if(isOprator(item)){
            if(stack.isEmpty()){
                stack.push(item);
            }else{
                if(item.equals(")")){
                    //入栈
                    stack.push(item);
                }else if(item.equals("(")){
                    //出栈输出,直至遇到(
                    String last = null;
                    while(!stack.isEmpty() && !( last = stack.pop()).equals("(")){
                        postfix.add(last);
                    }
                }else{
                    if(isGE(stack.peek(),item)){
                        //弹出直至优先级大于前面的运算符,或前面是数字
                        String last = null;
                        while(!stack.isEmpty() && isGE((last = stack.pop()),item)){
                            postfix.add(last);
                        }
                        stack.push(last);
                        stack.push(item);
                    }else{
                        //入栈
                        stack.push(item);
                    }
                }
            }

        }else{
            postfix.add(item);
        }
    }

    private static boolean isGE(String last, String item) {
        if(last.equals("+") || last.equals("-")){
            return item.equals("+") || item.equals("-");
        }else if(last.equals("*") || last.equals("/")){
            return true;
        }
        return false;
    }

    private static List<String> convertStrToItems(String e) {
        List<String> items = new ArrayList<>();

        String[] units = e.split("");
        int index = 0;
        for(String unit : units){
            if(isOprator(unit))  {
                items.add(index++,unit);
            }else{
                if(index == 0){
                    items.add(index++,unit);
                    continue;
                }
                String lastUnit = items.get(index-1);
                if(isOprator(lastUnit)){
                    items.add(index++,unit);
                }else{
                    items.remove(index-1);
                    items.add(index-1,lastUnit+unit);
                }
            }
        }
        return items;
    }

    private static boolean isOprator(String unit) {
        return unit.equals("+") || unit.equals("-") || unit.equals("*") || unit.equals("/")
                || unit.equals("(") || unit.equals(")");
    }
}

 

中缀表达式是我们常见的数学表达式的一种写法,它是以操作符位于操作数的两侧的形式来表示计算顺序。而前缀表达式后缀表达式中缀表达式的另外两种等价的写法。 将中缀表达式换为前缀表达式的方法如下: 1. 从右到左遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到前缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比顶操作符的优先级高,将操作符入。 - 如果操作符的优先级比顶操作符的优先级低或相等,弹出顶操作符,并将弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式。 4. 当遍历完中缀表达式后,将中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个前缀表达式,再将该前缀表达式。 5. 最后得到的顶即为换后的前缀表达式。 将中缀表达式换为后缀表达式的方法基本相同,只需将步骤3中操作符的优先级比较符号调整为"低或相等"即可。 中缀表达式后缀表达式的方法如下: 1. 从左到右遍历中缀表达式的每个字符。 2. 如果字符是操作数,直接输出到后缀表达式。 3. 如果字符是操作符,有两种情况: - 如果操作符的优先级比顶操作符的优先级高或为空,将操作符入。 - 如果操作符的优先级比顶操作符的优先级低或相等,弹出顶操作符,并将弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式。 4. 当遍历完中缀表达式后,将中的操作符依次弹出,并将每个弹出的操作符和操作数组合为一个后缀表达式,再将该后缀表达式。 5. 最后得到的顶即为换后的后缀表达式。 通过上述步骤,我们可以将中缀表达式换为前缀和后缀表达式
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值