棧的應用 -- 無括號表達式的求值
阿新 • • 發佈:2017-08-15
pow color stack bst ble 目前 integer key --
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 類型的運算 ,也沒有對表達式進行驗證, 後續有待完善
棧的應用 -- 無括號表達式的求值