Leecode刷题——栈和队列——逆波兰表达式求值(后缀表达式求值)

后缀表达式求值是非常典型的题目,这类题型一般使用二叉树的后序遍历来求解,本题使用栈的求解方式来解决

例题:150.逆波兰表达式求值

代码 :

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList<Integer>();
/*使用deque接口来实现栈,Java中栈接口stack本身的语意不不能很好的表述栈的数据结构,使用deque来实现栈更高效和准确,有两种实现方式:
使用LinkedList作为栈效率高(底层用链表来实现)。
使用ArrayDeque作为队列效率高(底层使用数组来实现)。
*/
        int n = tokens.length;
        for (int i = 0; i < n; i++) {
            String token = tokens[i];
            if (isNumber(token)) {
                stack.push(Integer.parseInt(token));
            } else {
                int num2 = stack.pop();
                int num1 = stack.pop();
                switch (token) {
                    case "+":
                        stack.push(num1 + num2);
                        break;
                    case "-":
                        stack.push(num1 - num2);
                        break;
                    case "*":
                        stack.push(num1 * num2);
                        break;
                    case "/":
                        stack.push(num1 / num2);
                        break;
                    default:
                }
            }
        }
        return stack.pop();
    }

    public boolean isNumber(String token) {
        return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
    }
}

总结点:首先说明一下本题的解题逻辑还是比较简单的:遍历字符串数组,遇到运算数则压栈,遇到运算符则将栈中前两个运算数弹栈做相应的运算然后再压栈,反复如此知道最后弹出结果。

1.后缀表达式

所谓后缀表达式就是中缀表达式(我们平常看到的计算式)的后缀形式即运算符在对应的运算数后面,这种形式能够让计算机更好地理解。例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算符号,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,这样是非常麻烦的,那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈里顺序处理,不需要考虑优先级了。

2.栈的实现

(1)Java中栈的实现一般不用stack而用deque接口来实现具体原因如下:Java是继承自vector的,因为Vector是当初JAVA曾经写得不太行的类,所以Stack也不太行。Vector不行是因为效率不太行,很多方法都用了synchronized修饰,虽然线程安全,但是像ArrayDeque,LinkedList这些线程不安全的,在需要安全的时候也可以用Collections.synchronizedCollection()转化成线程安全的,所以Vector就没什么用处了。再根据仿生学Stack只能上进上出,有点像刺胞动物(腔肠动物),就是那种从哪里吃进去就哪里拉出来的那种生活在海洋里的比较低级的生物。Deque上进上出,上进下出,甚至下进上出,非常上流,只有你想不到,没有我Deque做不到的。

(2)栈的实现有两种方法:

Deque<Integer> stack = new ArrayDeque<>();
Deque<Integer> stack = new LinkedList<>();
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
队列是数据结构中常用的两种数据结构,它们可以被用来实现表达式。下面是一个使用队列实现表达式的C语言例子: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_STACK_SIZE 100 #define MAX_QUEUE_SIZE 100 typedef enum { lparen, rparen, plus, minus, times, divide, mod, eos, operand } precedence; int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 }; int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 }; precedence getToken(char *symbol, int *n) { *symbol = expr[(*n)++]; switch (*symbol) { case '(': return lparen; case ')': return rparen; case '+': return plus; case '-': return minus; case '*': return times; case '/': return divide; case '%': return mod; case '\0': return eos; default: return operand; } } void postfix(void) { char symbol; precedence token; int n = 0; int top = 0; int queue_front = 0, queue_rear = 0; int stack[MAX_STACK_SIZE]; char queue[MAX_QUEUE_SIZE][MAX_STACK_SIZE]; stack[0] = eos; while ((token = getToken(&symbol, &n)) != eos) { if (token == operand) { queue[queue_rear][0] = symbol; queue[queue_rear++][1] = '\0'; } else if (token == rparen) { while (stack[top] != lparen) { queue[queue_rear][0] = stack[top--]; queue[queue_rear++][1] = '\0'; } top--; } else { while (isp[stack[top]] >= icp[token]) { queue[queue_rear][0] = stack[top--]; queue[queue_rear++][1] = '\0'; } stack[++top] = token; } } while ((token = stack[top--]) != eos) { queue[queue_rear][0] = token; queue[queue_rear++][1] = '\0'; } printf("Postfix expression: "); for (int i = queue_front; i < queue_rear; i++) { printf("%s", queue[i]); } printf("\n"); } int main() { char expr[MAX_STACK_SIZE]; printf("Enter an infix expression: "); scanf("%s", expr); postfix(expr); return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值