中缀表达式转后缀表达式

中缀表达式转后缀表达式

思路分析

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

代码实现

package 栈;

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

public class 中缀表达式转后缀表达式 {
    public static void main(String[] args) {
        String expression = "1+((2+3)*4)-5";//注意表达式 
                   List<String>infixExpressionList=toInfixExpressionList(expression);
        System.out.println("中缀表达式对应的 List=" + infixExpressionList); // ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]
         List<String> suffixExpreesionList = changeexpression(infixExpressionList);
        System.out.println("后缀表达式对应的 List" + suffixExpreesionList); //ArrayList [1,2,3,+,4,*,+,5,–]
    }

    //将中缀表达式list转为后缀表达式
    public static List<String> changeexpression(List<String> ls) {
        //定义两个栈,一个符号栈,一个数字栈
        Stack<String> s1 = new Stack<String>();//符号栈
        List<String> s2 = new ArrayList<>();//储存结果的栈

        for (String item : ls) {
            //如果是一个数,直接加入数栈
            if (item.matches("\\d+")) {
                s2.add(item);
            }
            //如果符号栈为空或者为左括号;优先级高于符号栈元素直接入符号栈;
            else if (item.equals("(")) {
                s1.push(item);
            }
            //如果为右括号,则在符号栈中弹出符号直接入数栈,直到遇到右括号,消除这对括号,将右括号pop出
            else if (item .equals(")") ) {
                while (!s1.peek() .equals("(") ) {
                    s2.add(s1.pop());
                }
                s1.pop();
            } else {
//优先级小于等于栈中元素,将 s1 栈顶的运算符弹出并压入到 s2 中,再次判断s1中下一个的情况
                while (s1.size()!=0 && opertion.getValue(s1.peek())>=opertion.getValue(item)) {
                    s2.add(s1.pop());
                }
                s1.push(item);
            }
        }
        //遍历结束,将s1全部压入s2中
        while (s1.size() != 0) {
            s2.add(s1.pop());
        }
        return s2;
    }

    //将中缀表达式转换为list
 public static List<String> toInfixExpressionList(String s) {
        //定义一个 List,存放中缀表达式 对应的内容
        List<String> ls = new ArrayList<String>();
        //这时是一个指针,用于遍历 中缀表达式字符串
        int i = 0;
        // 对多位数的拼接
        String str;
        // 每遍历到一个字符,就放入到 c
        char c;
      while(i<s.length()){
            //如果 c 是一个非数字,我需要加入到 ls
          if((c=s.charAt(i))<48 || (c=s.charAt(i))>57){
              ls.add("" + c);
               i++;
          }
          else{//如果是一个数,需要考虑多位数
              str = ""; //先将 str 置成"" '0'[48]->'9'[57]
       while(i<s.length()&& (c=s.charAt(i)) >= 48 && (c=s.charAt(i)) <= 57) {
                  str += c;//拼接
                  i++;
              }
              ls.add(str);
          }
        }
        return ls;//返回
    }
}

//创建一个运算类,用来判断符号的优先级
class opertion {
    public static int priority(String value) {
        int res = 0;

        if (value.equals("+")  || value.equals("-") ) {
            res = 1;
            return res;
        } else if (value.equals("*") || value.equals("/")) {
            res = 2;
            return res;
        } else {
            System.out.println("不存在");
        }
        return res;
    }
}

代码分析

主程序

定义中缀表达式

将中缀表达式转换为list集合

将中缀表达式转换为后缀表达式

成员方法

中缀表达式转换为集合元素

  1. 定义集合list、遍历中缀表达式指针i、字符串str用于拼接多位数、字符变量ch用来存放遍历到的每个字符;
  2. 循环遍历中缀表达式,while(i<index);
  3. 如果不是数字,直接添加到集合中;如果为数字需要判断是否为多位数,用while循坏判断是否为多位数,结束循环后,再将多位数添加到集合。

中缀表达式转换为后缀表达式

  1. 定义一个符号栈,定义一个集合模拟栈,用来存放遍历的值
  2. 遍历list集合,如果为数字(包括多位数)直接添加到集合s2;
  3. 如果为左括号,直接添加到符号栈s1;
  4. 如果是右括号,找到符号栈中为左括号的位置,将前面的元素pop出添加到集合中,最后pop出左括号;
  5. 否则优先级小于等于栈中元素,将 s1 栈顶的运算符弹出并压入到 s2 中,再次判断s1中下一个的情况
  6. 遍历结束,将s1全部压入s2中

判断优先级

注意使用item.equales()方法,不可以使用==来判断。


posted @ 2021-01-06 21:46  胡木杨  阅读(194)  评论(0)    收藏  举报