逆波兰表达式

逆波兰表达式

最近在复习数据结构,看到逆波兰表达式,顺手写一写

其实逆波兰表达式 也称后缀表达式,求值过程的话可以用栈来辅助存储,假设我们要求值的后缀表达式是 :

9 3 1 - 1 * + 10 2 / +

它的中序表达式是:

9 + (3 - 1) * 3 + 10 / 2

对逆波兰的表达式的求解就是:遍历表达式,读到运算符出栈两个数,做运算之后吧结果入栈,最后的元素就是我们要的结果。

中缀表达式的计算

我用的是两个栈来做的,也可以用一个队列和一个栈来做(栈存操作符,队列存操作数)

我标记一下:栈1做处理,栈2操作符

规则:

  1. 遍历中缀表达式
  2. 如果遇到 ( 符号,由于没有匹配,直接入栈2
  3. 如果遇到操作数,也就是数字,一直向后走,直到遇到非操作数,把这些数字全部入栈1
  4. 如果遇到 ) 符号,一直对栈2进行出栈操作,直到匹配到 ( ,中间栈2出栈的元素,全部入栈1,括号这些不进栈1哈
  5. 如果遇到操作符,如果栈2顶部元素的操作数级别大于等于我们这个操作符,也进行出栈2,入栈1的操作,最后吧操作符入栈2
  6. 最后了,吧栈2 还剩的元素,全部移入栈1

因为我用的栈存的,所以我需要转个顺序,存到链表中

上代码了哦

package stack;

import java.util.*;

/**
 * Class SuffixExpression ...
 *
 * @author LiJun
 * Created on 2019/4/12
 */
public class SuffixExpression {
    /**
     * 对比操作数大小的函数
     *
     * @param s 操作数
     * @return integer数
     */
    private int getSize(String s) {
        // 如果是 * 和 / 说明他们级别高
        if ("*".equals(s) || "/".equals(s)) {
            return 1;
        }// 如果是- 和 +  级别低 
        else if ("-".equals(s) || "+".equals(s)) {
            return 0;
        }
        // 这里主要是处理其余的符号 比如 ( 之类的
        return -1;
    }

    /**
     * 把传进来的中序表达式转换成逆波兰表达式
     *
     * @return 转换后的逆波兰表达式
     */
    public List<String> parseSuffixExpression(String str) {
        if (str == null) {
            return null;
        }
        // 先进行格式化
        str = getNormal(str);
        // 用来处理结果的
        Stack<String> stack1 = new Stack<>();
        // 存操作数的
        Stack<String> stack2 = new Stack<>();
        assert str != null;
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            // 如果是 ( 直接入栈
            if (chars[i] == '(') {
                stack2.push(chars[i] + "");
            } else if (chars[i] == ')') {
                // 如果是) 出栈到第一个 "("
                while (!stack2.empty() && !"(".equals(stack2.peek())) {
                    stack1.push(stack2.pop());
                }
                if (!stack2.empty()) {
                    stack2.pop();
                }
            } else if (chars[i] >= '0' && chars[i] <= '9') {
                // 如果是数字,向后走,找到所有数字
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(chars[i]);
                for (int j = i + 1; j < chars.length; j++) {
                    if (chars[j] < '0' || chars[j] > '9') {
                        i = j - 1;
                        break;
                    } else {
                        stringBuilder.append(chars[j]);
                        i = j;
                    }
                }
                stack1.push(stringBuilder.toString());
            } else {
                // 如果是操作数,如果栈顶元素级别高,一直出栈2 入栈1
                while (!stack2.empty() && getSize(stack2.peek()) >= getSize(chars[i] + "")) {
                    stack1.push(stack2.pop());
                }
                stack2.push(chars[i] + "");
            }
        }
        // 如果栈2不空,全部移入栈1
        while (!stack2.empty()) {
            stack1.push(stack2.pop());
        }
        // 反转一下结果 存入 list
        List<String> list = new LinkedList<>();
        while (!stack1.empty()) {
            list.add(0, stack1.pop());
        }
        return list;
    }

    /**
     * 计算逆波兰表达式的值
     *
     * @param str 逆波兰表达式
     * @return 结果
     */
    public int getResult(List<String> str) {
        Stack<Integer> stack = new Stack<>();
        for (String s : str) {
            if ("*".equals(s)) {
                stack.push(stack.pop() * stack.pop());
            } else if ("-".equals(s)) {
                stack.push(-stack.pop() + stack.pop());
            } else if ("+".equals(s)) {
                stack.push(stack.pop() + stack.pop());
            } else if ("/".equals(s)) {
                int one = stack.pop();
                int two = stack.pop();
                stack.push(two / one);
            } else {
                stack.push(Integer.parseInt(s));
            }
        }
        if (stack.size() == 1) {
            return stack.pop();
        }
        return 0;
    }

    /**
     * 处理一些特殊的字符
     *
     * @param str 字符串
     * @return 处理结果
     */
    private String getNormal(String str) {
        if (str == null) {
            return null;
        }
        // 去掉空格
        str = str.replace(" ", "");
        // 处理中文字符
        str = str.replace("(", "(");
        str = str.replace(")", ")");
        str = str.replace("X", "*");
        str = str.replace("x", "*");
        return str;
    }

    public static void main(String[] args) {
        String string = "9+(3-1)*3+10/2";
        SuffixExpression expression = new SuffixExpression();
        List<String> list = expression.parseSuffixExpression(string);
        System.out.println(list);
        System.out.println(expression.getResult(list));

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值