波兰逻辑学家的逆波兰表达式 思路

带小括号的中转后缀表达式:
1.初始化两个栈,运算符栈s1和中间结果栈s2
2.从左至右扫描中缀表达式
3.遇到数字时,将其压入s2
4.遇到运算符时,比较当前运算符与s1栈顶运算符的优先级:
①如果s1为空,或s1栈顶运算符为左括号(,则直接将此运算符入栈。
②否则,若优先级比栈顶运算符高,也将运算符压s1
③否则,将s1栈顶的运算符弹出并压入到s2中,再次从开始与s1中新的栈顶运算符相比较。
5.遇到括号时:
①如果是(,则直接压入s1.
②如果是),则依次弹出s1栈顶运算符并压入s2中直到遇到(为止。
6.重复2-5,直至结束。
7.将s1中剩余运算符弹出压入s2.

package.数组模拟栈.中缀转后缀;

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

public class PolandCalculator {
    public static void main(String[] args) {
        String input = "1+(2+3*4)-3";
        List<String> list = infixToListparseSuf(input);
        List<String> suffixList = parseSuffixExpressionListparseSuf(list);
        int res = calculatePriority(suffixList);
        System.out.println(res);
    }

    public static List<String> infixToListparseSuf(String input){
        ArrayList<String> list = new ArrayList<>();
        int i = 0;
        String str = "";
        char c;
        do{
            if ((c = input.charAt(i)) < 48 || (c = input.charAt(i)) > 57) { // 如果是运算符
                list.add(""+c);
                i++;
            }else {
                str = "";
                while (i < input.length() && (c = input.charAt(i)) >= 48 && (c = input.charAt(i)) <= 57) {
                    str += c;
                    i++;
                }
                list.add(str);
            }
        }while (i<input.length());
        return list;
    }

    /**
     * 中缀转后缀
     * @param list
     * @return
     */
    public static List<String> parseSuffixExpressionListparseSuf(List<String> list) {
        Stack<String> stack = new Stack<>();
        ArrayList<String> queue = new ArrayList<>();

        for (String item : list) {
            if (item.matches("\\d+")) { // 凡是遍历到数字就放到list中
                queue.add(item);
            }
            if ("(".equals(item)) { // 凡是( 就压栈
                stack.push(item);
            }
            if (")".equals(item)) {
                while (!"(".equals(stack.peek())) { // 凡不是(也就是右括号就弹出栈顶运算符压入s2,直到遇到(为止。消除()括号
                    queue.add(stack.pop());
                }
                stack.pop();
            }
            if (!item.matches("\\d+")) {
                // 如果当前运算符小于栈顶运算符优先级
                while (stack.size() != 0 && Operation.getPriority(item) <= Operation.getPriority(stack.peek())) {
                    queue.add(stack.pop()); // 栈顶的优先级高必须先弹出去s2
                }
                stack.push(item);
            }
        }
        while (stack.size() != 0) {
            queue.add(stack.pop());
        }
        return queue;
    }

    /**
     * 计算后缀表达式最终运算结果
     * @param suffic
     * @return
     */
    public static int calculatePriority(List<String> suffic) {
        Stack<String> stack = new Stack<>();
        for (String item : suffic) {
            if (item.matches("\\d+")) {
                stack.push(item);
            }
            if (!item.matches("\\d+")) {
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                if ("+".equals(item)) {
                    res = num1 + num2;
                }
                if ("-".equals(item)) {
                    res = num1-num2;
                }
                if ("*".equals(item)) {
                    res = num1*num2;
                }
                if ("/".equals(item)) {
                    res = num1/num2;
                }
                stack.push(""+res);
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

class Operation {

    public static int getPriority(String opert) {
        int level = 0;
        switch (opert) {
            case "+":
                level = 1;
                break;
            case "-":
                level = 1;
                break;
            case "*":
                level = 2;
                break;
            case "/":
                level = 2;
                break;
        }
        return level;

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值