中缀表达式转后缀表达式

具体步骤

  1. 初始化两个栈:运算符栈s1和储存中间结果的栈s2 在实际过程中,s2没有涉及到出栈操作,所以可以直接使用list代替(这样方便逆序);

  2. 从左到又扫描中缀表达式;

  3. 遇到操作数时,将其压如s2;

  4. 遇到运算符时,比较其与s1栈顶运算符的优先级:

    4.1. 如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符入栈;

    4.2. 否则,若优先级比栈顶运算符的高,也将运算符压入s1中;

    4.3. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到4.1与s1中新栈顶运算符比较;

  5. 遇到括号时:

    5.1. 如果是"(",直接压入s1;

    5.2. 如果是")",则一次弹出s1的栈顶元素,并压入s2,直到遇上"("为止,此时将这一对括号丢弃

  6. 重复2到5,直到表达式到达最右边

  7. 将s1中剩余的运算符依次弹出并压入s2

  8. 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式.

代码实现

public class infixToSuffix {
    public static void main(String[] args) {
        //定义一个中缀表达式
        String expression = "1+((2+3)*4)-5";
        //先将中缀表达式转换成list,方便操作
        List<String> infixList = inFixToList(expression);
        System.out.println("中缀表达式list = "+infixList);
        //将中缀表达式转换成后缀表达式
        List<String> suffixList = infixToSuffixList(infixList);
        System.out.println("后缀表达式list = "+suffixList);
    }

    /**
     * 将中缀表达式转换成后缀表达式
     * @param infixList 中缀表达式的list
     * @return
     */
    private static List<String> infixToSuffixList(List<String> infixList) {
        //初始化一个栈,存放符号
        Stack<String> stack = new Stack();
        //初始化一个数组存放结果(分析使用的栈,因为没有出栈操作,所以不需要使用栈实现,直接用list更加方便)
        List<String> suffixList = new ArrayList<>();
        for (String s : infixList) {
            //如果是数字,直接添加到结果list中
            if (s.matches("\d+")){
                suffixList.add(s);
            }else if (s.equals("(")){ //如果是"(" 直接入符号栈
                stack.push(s);
            }else if (s.equals(")")){ //如果是")",则需要把符号栈中的符号出栈,把运算符添加到结果list中,直到匹配到"(",且"("出栈
                while (!stack.peek().equals("(")){
                    suffixList.add(stack.pop());
                }
                //出栈"("
                stack.pop();
            }else { //如果是运算符,则需要比较优先级
                //栈中运算符的优先级大于等于当前的,则出栈,且添加到结果list中
                while (stack.size() !=0 && Priority.getPriority(s)<=Priority.getPriority(stack.peek())){
                    suffixList.add(stack.pop());
                }
                //栈中运算符的优先级小于当前的,入栈
                stack.push(s);
            }

        }
        //将栈中剩余的运算符取出,添加到结果list中
        while (stack.size()!=0){
            suffixList.add(stack.pop());
        }
        return suffixList;
    }

    /**
     * 将中缀表达式转换成list
     * @param expression
     * @return
     */
    private static List<String> inFixToList(String expression) {
        List<String> infixList = new ArrayList<>();
        int index = 0;  //遍历字符串指针
        String str = "";  //合并多位数
        char ch;
        //数字的ASCII 49~57
        while (index < expression.length()){
            ch = expression.charAt(index);
            //字符不是数字
            if (ch < 49 || ch > 57){
                infixList.add(""+ch);
                index ++;

            }else {
                //是数字,判断是否为多位数,是就拼接
                //拼接之前,先置空
                str = "";
                while (index<expression.length() && (ch=expression.charAt(index))>=49 &&
                        (ch=expression.charAt(index))<=57){
                    str+=ch;
                    index ++;

                }
                infixList.add(str);
            }

        }
        return infixList;
    }
}

class Priority{
    //这里只考虑加减乘除
    private static final int ADD = 1;
    private static final int SUB = 1;
    private static final int MUL = 2;
    private static final int DIV = 2;

    /**
     *
     * @param op 操作符
     * @return返回优先级
     */
    public static int getPriority(String op){
        int res = 0;
        switch (op){
            case "+":
                res = ADD;
                break;
            case "-":
                res = SUB;
                break;
            case "*":
                res = MUL;
                break;
            case "/":
                res = DIV;
                break;
            default:
                break;
        }
        return res;
    }
}
原文地址:https://www.cnblogs.com/liuzhidao/p/13798804.html