【数据结构与算法篇】什么是后缀表达式?

什么是后缀、前缀、以及中缀表达式呢?他与我们平时在数学中见到的表达式有什么区别?第一次看这个名词,我还是有点蒙,难理解,所以做以下笔记,以便日后复习,也希望可以帮助读者,以相互促进。

文章目录

前言:

一、什么是前、中、后缀表达式?

二、思路与分析:

三、实操代码(示例):

总结:


前言:

在学习数据结构与算法中,我们会见到前缀表达式、中缀表达式、后缀表达式,用来编写逆波兰计算器。那么什么是前中后、缀表达式呢?下面我们通过中缀表达式为引讲解。


一、什么是前、中、后缀表达式?

前、中、后缀表达式中,运算符在算式中的位置决定了他是前缀还是中后缀;

什么是后缀表达式?他与我们平时见到的表达式有什么区别?

      解:我们平时在数学中见到的一般表达式我们称它为中缀表达式,呢么为什么要叫这个名字呢?百度给出如下说法:

中缀表达式(又称中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作符的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。

与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。

与前缀或后缀记法不同的是,在中缀记法中括号是必需的计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。

呢么我们就可以得出结论,前中后缀表达式实际上就是运算符在操作数之间出现的位置,在两个操作数之前,我们称为前缀表达式,在中间叫中缀表达式,后面就叫后缀表达式。

这里值得注意的是,在中缀表达式中会有括号这种符号,来区分运算的先后。

二、思路与分析:

在了解了前、后、中表达式后,下面我们看如何将一个中缀表达式转化为后缀表达式, 在写代码之前我们先顺一下思路,和步骤。

  1. 初始化一个存放运算符的栈。
  2. 对算术表达式从左向右进行扫描直到串尾:对获取的符号进行判断:

            2.1)如果是数字:继续读取下一位,判断下一位是不是数字,  

                        2.1.1)如果是数字:就将第二次读取的数字与之前的数字进行拼接,(在这之前我们需要定义一个空的字符串用来拼接数字)具体怎么拼接呢?(我们首先将第一次读取的数字,与空字符串拼接,在第二次读取的数字与字符串拼接,最后用Integer.parseInt(String str);方法将字符串转为整数)。 
                         2.1.2)如果不是数字:就直接把第一次读取的数字直接输出到后缀表达式中.
           2.2)如果是左括号:把左括号入运算符栈如果是右括号:把栈顶元素依次出栈到后缀表达式中,直到遇到运算符栈中的左括号,并把左括号出栈2.3)如果是运算符:

如果该运算符的优先级高于栈顶运算符优先级,该运算符入栈;否则把(低于或等于)该运算符优化级的栈顶元素依次出栈到后缀表达式中,直到该运算符的优先级高于栈顶运算符为止,之后该运算符入运算符栈

    3. 如果到串尾时,将符号栈中的所以元素依次出栈到后缀表达式中2.读入数据

三、实操代码(示例):

public class InfixToSuffix {
    public static void main(String[] args) {
        String infixExpretion = "1+((2+3)*4)-5";
        List<String> strings = toInfixExpression(infixExpretion);
        List<String> list = parseSuffixExpressionList(strings);
        System.out.println(list);
    }

    public static List<String> toInfixExpression(String infixExpression){
        List<String> ls = new ArrayList<>();
        char c;
        String str;
        int i=0;
        do{
            if ((c=infixExpression.charAt(i)) <= 48 || (c=infixExpression.charAt(i)) >= 57){
                ls.add("" + c);
                i++;
            }else{
                str = "";
                    while (i<infixExpression.length() && (c=infixExpression.charAt(i)) >= 48 && (c=infixExpression.charAt(i)) <= 57){
                        str += c;
                        i++;
                    }
                    ls.add(str);
            }
        }while (i<infixExpression.length());
        return ls;
    }

    public static List<String> parseSuffixExpressionList(List<String> list){
        Stack<String> operStack = new Stack<>();
        List<String> resList = new ArrayList<>();
         for (String item : list){
             if (item.matches("\\d+")){
                 resList.add(item);
             }else if (item.equals("(")){
                 operStack.push(item);
             //如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号,此时将这一对括号丢弃;
             }else if (item.equals(")")){
                 while (!operStack.peek().equals("(")){
                     resList.add(operStack.pop());
                 }
                 operStack.pop();
             }else{
                 while (operStack.size()!=0 && Operation.getValue(operStack.peek()) >= Operation.getValue(item)){
                     resList.add(operStack.pop());
                 }
                 operStack.push(item);
             }
         }
         while (operStack.size()!=0){
             resList.add(operStack.pop());
         }
         return resList;
    }
}

class Operation{
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 1;
    private static int DIV = 1;
    private static int LEFT = 0;

    public static int getValue(String oper){
        int res = 0;
        switch (oper){
            case "+":
                res = ADD;
                break;
            case "-":
                res = SUB;
                break;
            case "*":
                res = MUL;
                break;
            case "/":
                res = DIV;
                break;
            case "(":
                res = LEFT;
                break;
            default:
                System.out.println("不存在该运算符");
                break;
        }
        return res;
    }
}


总结:

以上就是今天要讲的内容,本文仅仅简单介绍了前、中、后缀表达式,而前中后缀表达式是数据结构中很重要的一部分,后面我们会在编写逆波兰计算器中用到。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值