zoukankan      html  css  js  c++  java
  • 栈的应用 -- 无括号表达式的求值

    package com.learn.algorithm.expression;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Stack;
    
    /**
     * 无括号表达式求值
     * @author Jiekun.Cui
     *
     */
    public class Expression {
        
        
        /**
         * 操作符的优先级定义
         */
        public static Map<String,Integer> optProirity = null;
        static{
            optProirity = new HashMap<>();
            optProirity.put("+", 100);
            optProirity.put("-", 100);
            optProirity.put("*", 200);
            optProirity.put("/", 200);
            optProirity.put("^", 300);//乘幂
            
        }
        
        public static void main(String[] args) throws Exception {
            String s = "11+2-41*6/2+3^3-88";
            
            
            System.out.println(getExpressionValue(s));
        }
    
        private static Number getExpressionValue(String exp) throws Exception {
            Stack<String> optr = new Stack<>(); //运算符栈
            Stack<Number> ovs = new Stack<>(); //运算数栈
            
            StringBuilder sb = new StringBuilder("");
             
            for (int i = 0; i < exp.length(); i++) {
                String t = exp.substring(i, i+1);
                
                if(optProirity.containsKey(t)){
                    
                    ovs.push( Integer.valueOf(sb.toString()) );
                    sb = new StringBuilder("");
                    
                    if ( optr.isEmpty() ) {
                        optr.push(t);
                    } else {
                        
                        //把要进栈的运算符和当店栈顶的运算符进行比较,判断当前是否需要进行运算
                        while ( !(optProirity.get( optr.peek() ) < optProirity.get(t)) ) { 
                            
                            Number n2 = ovs.pop();
                            Number n1 = ovs.pop();
                            
                            ovs.push( calcu(n1, n2, optr.pop()) );
                            
                            if(optr.isEmpty()){
                                break;
                            }
                        }
                        
                        optr.push(t);
                        
                    }
                        
                    
                } else {
                    sb.append(t);
                }
                
            }
            
            
            ovs.push( Integer.valueOf(sb.toString()) );//将最后一个操作数进栈
            
            while ( !optr.isEmpty() ) { //运算符栈不为空则继续进行运算
                Number n2 = ovs.pop();
                Number n1 = ovs.pop();
                ovs.push( calcu(n1, n2, optr.pop()) );
            }
            
            return ovs.peek();
        }
        
        
        public static Number calcu(Number n1,Number n2,String opt) throws Exception{
            
            switch (opt) {
            case "+":
                return n1.intValue() + n2.intValue();
            case "-":
                return n1.intValue() - n2.intValue();
            case "*":
                return n1.intValue() * n2.intValue();
            case "/":
                return n1.intValue() / n2.intValue();
            case "^":
                return ( (Double)Math.pow(n1.intValue(), n2.intValue()) ).intValue();
            default:
                throw new Exception("错误的运算符:" +  opt);
            }
            
        }
        
        
    
    }

    目前只是实现了 Integer 类型的运算 ,也没有对表达式进行验证, 后续有待完善

  • 相关阅读:
    python之squid实现免费 IP代理 (windows win7 单机 本机 本地 正向代理 区分 HTTPS)
    python之PIL 二值图像处理和保存
    python之GIL release (I/O open(file) socket time.sleep)
    python之多线程 threading.Lock() 和 threading.RLock()
    python之GIL官方文档 global interpreter lock 全局解释器锁
    python多线程之t.setDaemon(True) 和 t.join()
    python之工作目录和文件引用
    python 代理
    原 浅谈移动端开发--物理像素和逻辑像素
    解决移动端页面在苹果端滑不到底部的问题
  • 原文地址:https://www.cnblogs.com/Jiekun-Cui/p/7367950.html
Copyright © 2011-2022 走看看