• 逆波兰计算器


    package com.dai.stack;
    
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Stack;
    
    import javax.sql.rowset.JoinRowSet;
    import javax.swing.text.AbstractDocument.BranchElement;
    public class PolandNotation {
    
        public static void main(String[] args) {
            //将中缀表达式转后缀表达式
            //直接扫描字符串不方便,不妨先将字符串转化成中缀对应的List
            
            String expression = "1+((2+3)*4)-5";
            List<String> infixExpressionList = toInfixExpressionList(expression);
            System.out.println("中缀表达式对应的List" + infixExpressionList);
            List<String> parseSuffixExpressionList = parseSuffixExpressionList(infixExpressionList);
            System.out.println("后缀表达式对应的list:"+ parseSuffixExpressionList);
            System.out.println(expression+ "=" + calculate(parseSuffixExpressionList));
        
        }
            //定义一个逆波兰表达式
            //(3+4)*5-6
            /*String suffixExpression  = "3 4 + 5 * 6 -";
            //
            List<String> rpnList = getListString(suffixExpression);
            System.out.println("rpnList" + rpnList);
            
            int res = calculate(rpnList);
            System.out.println("计算的结果是=" + res);
         }
         
        //将中缀表达式转化成对应的List*/
        
        //将中缀List转为后缀List
        public static List<String> parseSuffixExpressionList(List<String> ls){
            //定义两个栈
            Stack<String> s1 = new Stack<String>(); //符号栈
            //s2在整个过程中没有pop操作,还要逆序输出,直接用List 替代更好
            //Stack<String> s2 = new Stack<String>(); //存中间结果的栈
            List<String> s2 = new ArrayList<String>();
            //遍历ls
            for(String item : ls) {
                //如果是一个数,就加入到s2
                if(item.matches("\d+")) {
                    s2.add(item);
                }else if (item.equals("(")) {
                    s1.push(item);
                }else if (item.equals(")")) {
                    while (!s1.peek().equals("(")) {
                        s2.add(s1.pop());
                    }
                    s1.pop(); //将小括号弹出栈
                }else {
                    //当item优先级<=栈顶的优先级,将s1栈顶弹出加入到s2
                    while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
                        s2.add(s1.pop());
                    }
                    //将item压入栈
                    s1.push(item);
                }
            }
            while(s1.size() != 0) {
                s2.add(s1.pop());
            }
            return s2;
        }
        
        //将中缀转为List
        public static List<String> toInfixExpressionList(String s){
            List<String> ls = new ArrayList<String>();
            int i = 0; //指针,用于遍历字符串
            String str; //多位数拼接
            char c;
            do {
                //如果c非数字,则加入ls
                if((c=s.charAt(i))<48 || (c=s.charAt(i))>57) {
                    ls.add(""+c);
                    i++;
                }else{//考虑多位数
                    str = "";
                    while(i < s.length() && (c=s.charAt(i))>=48 && (c=s.charAt(i))<=57) {
                        str += c;
                        i++;
                    }
                    ls.add(str);
                }
            } while (i < s.length());
            return ls;
        }
        //将逆波兰表达式,依次将数据和运算符 放入到ArrayList中
        public static List<String> getListString(String suffixExpression){
            //将sufffixExpression 分割
            String[] split = suffixExpression.split(" ");
            List<String> list = new ArrayList<String>();
            for(String ele : split) {
                list.add(ele);
            }
            return list;
        }
        
        //完成对逆波兰表达式的计算
        public static int calculate(List<String> ls) {
            //创建一个栈即可
            Stack<String> stack = new Stack<String>();
            //遍历ls
            for(String item:ls) {
                //使用正则表达式取数
                if (item.matches("\d+")) {//匹配的是多位数
                    //入栈
                    stack.push(item);
                }else {
                    //pop出两个数,并运算,再入栈
                    int num2 = Integer.parseInt(stack.pop());
                    int num1 = Integer.parseInt(stack.pop());
                    int res = 0;
                    if(item.equals("+")) {
                        res = num1+num2;
                    }else if (item.equals("-")) {
                        res = num1 - num2;
                    }else if (item.equals("*")) {
                        res = num1 * num2;
                    }else if (item.equals("/")) {
                        res = num1 / num2;
                    }else {
                        throw new RuntimeException("运算符有误!");
                    }
                    stack.push(res+"");
                }
            }
            //最后留下来的就是结果
            return Integer.parseInt(stack.pop());
        }
    
    }
    
    //一个可以返回运算符优先级的类
    class Operation{
        private static int ADD = 1;
        private static int SUB = 1;
        private static int MUL = 2;
        private static int DIV = 2;
        
        public static int getValue(String operation) {
            int result = 0;
            switch (operation) {
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                //throw new RuntimeException("运算符非法");
                break;
            }
            return result;
        }
    }
  • 相关阅读:
    多线程访问成员变量与局部变量
    Could not resolve placeholder 解决方案
    instanceof, isinstance,isAssignableFrom的区别
    YYYY-mm-dd HH:MM:SS
    整合Spring Data JPA与Spring MVC: 分页和排序
    dubbo配置文件xml校验报错
    安装eclipse插件时出现问题
    Windows上搭建hadoop开发环境
    jquery validate 在ajax提交表单下的验证方法
    HDU 1698 Just a Hook(线段树区间替换)
  • 原文地址:https://www.cnblogs.com/shengtudai/p/14369991.html
Copyright © 2020-2023  润新知