【数据结构与算法|栈篇】中缀表达式转变为后缀表达式

1. 前言

假设我们已经知道中缀表达式和后缀表达式的概念. 我们可以用符号栈来实现中缀表达式向后缀表达式的转变.

2. 符号栈实现中缀表达式转变为后缀表达式

(1). 思路

我们设计了可变字符串与符号栈. 如果传入的字符串的字符是数字字符,则直接将该字符append到stringbuilder中. 如果该字符是符号字符,首先先判断符号栈是否为空,如果为空,则直接将该字符压栈,如果不为空,则需要将该字符与栈顶字符进行优先级比较.如果栈顶元素的优先级>该字符,毫无疑问,直接将栈顶元素弹栈.如果栈顶元素与该元素优先级相等,由于计算的顺序是从左到右,所以仍然需要将栈顶元素弹栈. 弹栈过程结束以后,需要将该字符压栈.

(2). 解

java 复制代码
//将中缀表达式转变为后缀表达式
//目前只讨论没有小括号的情况
public class postfixexpr {
    public StringBuilder postfix(String s) throws Exception {
        //符号栈
        Deque<Character> deque = new LinkedList<>();
        StringBuilder str = new StringBuilder();
        int i = 0;
        for (; i < s.length(); i++) {
            char c = s.charAt(i);
            //如果该字符是数字字符, 那么将该字符加入到可变字符串
            if(isNumber(c)) {
                str.append(c);
            } else {
                //如果栈空, 则直接将该符号压栈
                //如果不为空, 则将栈顶元素与该字符作比较
                //if栈顶元素优先级大于等于该元素, 全部弹栈
                if(deque.isEmpty()) {
                    deque.push(c);
                } else {
                    while(!deque.isEmpty() && priority(deque.peek()) >= priority(c)){
                        str.append(deque.pop());
                    }
                    deque.push(c);
                }
            }
        }
        while(!deque.isEmpty()) {
            str.append(deque.pop());
        }
        return str;
    }

    //设计判断符号优先级的函数
    private int priority(char c) throws Exception {
        if (c == '+' || c == '-') {
            return 1;
        } else if (c == '*' || c == '/') {
            return 2;
        } else {
            throw new Exception();
        }
    }
    private boolean isNumber(char c) {
        if (c == '+' || c == '-' || c == '*' || c == '/') {
            return false;
        }
        return true;
    }
}

(3). 单元测试

java 复制代码
public class postfixexprTest {
    @Test
    public void test() throws Exception {
        postfixexpr pf = new postfixexpr();
//        System.out.println(pf.postfix("a+b*c"));
        //abc*+
        System.out.println(pf.postfix("a*b-c/d"));
        //ab*cd/-
    }
}

3. 带小括号的中缀表达式转变为后缀表达式

(1). 思路

将括号的优先级设置为最低,避免括号提前出栈. 如果是左括号,直接将其入栈,如果遇到右括号,一直出栈,直到遇到左括号,此时再将左括号出栈. 遇到其他符号情况与上同.

(2). 解

java 复制代码
public class postfixexpr2 {
    public StringBuilder postfix(String s) throws Exception {
        //符号栈
        Deque<Character> deque = new LinkedList<>();
        StringBuilder str = new StringBuilder();
        int i = 0;
        for (; i < s.length(); i++) {
            char c = s.charAt(i);
            //如果该字符是数字字符, 那么将该字符加入到可变字符串
            if(isNumber(c)) {
                str.append(c);
            } else {
                if(deque.isEmpty()) {
                    deque.push(c);
                } else {
                    if(c == '(') {
                        deque.push(c);
                    }else if(c == ')') {
                        while(deque.peek() != '(') {
                            str.append(deque.pop());
                        }
                        //将字符'('弹栈
                        deque.pop();
                    } else {
                        while(!deque.isEmpty() && priority(deque.peek()) >= priority(c)){
                            str.append(deque.pop());
                        }
                        deque.push(c);
                    }

                }
            }
        }
        while(!deque.isEmpty()) {
            str.append(deque.pop());
        }
        return str;
    }

    //设计判断符号优先级的函数
    private int priority(char c) throws Exception {
        if (c == '+' || c == '-') {
            return 1;
        } else if (c == '*' || c == '/') {
            return 2;
        } else if(c == '('){
            return 0;
        } else {
            throw new Exception();
        }
    }
    private boolean isNumber(char c) {
        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')') {
            return false;
        }
        return true;
    }
}

(3). 单元测试

java 复制代码
public class postfixexpr2Test {
    @Test
    public void test() throws Exception {
        postfixexpr2 pf = new postfixexpr2();
//        System.out.println(pf.postfix("(a+b)*c"));
        //ab+c*
        System.out.println(pf.postfix("a*(b+c)"));
        //abc+*
    }
}
相关推荐
艾莉丝努力练剑1 小时前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
_殊途3 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
珊瑚里的鱼6 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
秋说7 小时前
【PTA数据结构 | C语言版】顺序队列的3个操作
c语言·数据结构·算法
lifallen8 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
liupenglove8 小时前
自动驾驶数据仓库:时间片合并算法。
大数据·数据仓库·算法·elasticsearch·自动驾驶
python_tty9 小时前
排序算法(二):插入排序
算法·排序算法
然我9 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法
risc1234569 小时前
BKD 树(Block KD-Tree)Lucene
java·数据结构·lucene
F_D_Z10 小时前
【EM算法】三硬币模型
算法·机器学习·概率论·em算法·极大似然估计