中缀表达式转后缀表达式(逆波兰表达式)

中缀表达式转后缀表达式(逆波兰表达式)

1.初始化一个栈和集合:运算符栈stack和储存中间结果的集合list;
2.从左至右扫描中缀表达式;
3.遇到操作数时,将其存入list;
4.遇到运算符时,比较其与stack栈顶运算符的优先级:
 (1)如果stack为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
 (2)否则,若优先级比栈顶运算符的高,也将运算符压入stack;
 (3)否则,将stack栈顶的运算符弹出并存入到list中,再次转到步骤4.1与stack中新的栈顶运算符相比较; 
5.遇到括号时:
   (1)如果是左括号"(",则直接压入stack
   (2)如果是右括号")",则依次弹出stack栈顶的运算符,并存入list,直到遇到左括号为止,此时将这一对括号丢弃
6.重复步骤2至5,直到表达式的最右边
7.将stack中剩余的运算符依次弹出并存入list
8.list中的元素即为中缀表达式对应的后缀表达式

中缀表达式转后缀表达式具体的实现可以参考网上资料,有许多在此不细说了。

本代码主要参考了尚硅谷的数据结构与算法课程,在其基础上做了一些改进。

可以满足整数的简单四则运算。

首先将中缀表达式从String转换为list,才好进行计算

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

public class ToSuffixExpression {
     /**
     * 将字符串表达式转换成list集合
     * @param s
     * @return 中缀表达式的list集合
     */
    public static List<String> toInfixExpressionList(String s) {
        List<String> list = new ArrayList<>();
        //遍历字符串的指针
        int i = 0;
        //用来保存多位数
        String str = "";
        for (char c : s.toCharArray()) {
            i++;
            //用ASCII来匹配非数字字符,即运算符
            if(c < 48 || c > 57){
                //碰到运算符就将它的上一个多位数存进list
                if(str != ""){
                    list.add(str);
                    str = "";
                }
                list.add("" + c);
            }else{
                str += c;
                //最后一位字符是数字时,直接将str代表的多位数存入list
                if(i == s.length()){
                    list.add(str);
                }
            }
        }
        return list;
    }
 
    /**
     * 将中缀表达式换成后缀表达式
     * @param ls
     * @return 后缀表达式的list集合
     */
    public static List<String> parseSuffixExpressionList(List<String> ls) {
        //符号栈
        Stack<String> stack = new Stack<>();
        //后缀表达式栈,只用存数据,不需要pop操作,所以用list集合代替
        ArrayList<String> list = new ArrayList<>();
        for (String l : ls) {
            //正则表达式匹配数字,存入到后缀表达式栈中
            if(l.matches("\\d+")){
                list.add(l);
            }else if(l.equals("(")){
                //左括号存入到符号栈中
                stack.push(l);
            }else if (l.equals(")")){
                //如果是右括号,则依次弹出stack栈顶的运算符,并压入list,知道遇到左括号为止,然后将左括号弹出,完成去掉括号的操作
                while(! (stack.peek().equals("("))){
                    list.add(stack.pop());
                }
                //弹出左括号,完成去掉括号的操作
                stack.pop();
            }else{
                //当l运算符的优先级小于或等于stack栈顶运算符,将stack栈顶的运算符弹出并压入list中,再次转到4.1步骤中与stack中新的栈顶运算符相比较
                //首先判断stack运算符栈不为空,然后写一个方法用来比较运算符优先级
                while(stack.size() != 0 && getPriority(l) <= getPriority(stack.peek())){
                    list.add(stack.pop());
                }
                //l运算符优先级大于stack栈顶运算符,或stack运算符栈为空,直接将l压入stack中
                stack.push(l);
            }
        }
        //将stack中剩余的运算符依次弹出加入s2
        while(! stack.isEmpty()){
            list.add(stack.pop());
        }
        return list;
    }

    /**
     * 获取运算符优先级的方法
     * @param s
     * @return 运算符优先级
     */
    private static int getPriority(String s){
        if("+".equals(s) || "-".equals(s)){
            return 0;
        }else if("*".equals(s) || "/".equals(s)){
            return 1;
        }
        return -1;
    }
}

到这里我们就获得了将中缀表达式转换成后缀表达式的方法,接下就是对后缀表达式进行计算,可以参考文章:

后缀表达式的计算方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值