逆波蘭表達式

最近在作一個知識產權的項目,被知識產權各類複雜的收費方式搞得煩死。因而想寫一個通用的費用計算方式,操做人員能夠在後臺爲每一個國家各類不一樣的知識產權產品設訂價格計算公式,系統調用公式便可算出結果,這樣也方便之後增長其餘國家的知識產權產品,方便設訂價格。java

主要面臨的難點有:git

不一樣國家的知識產權收費項目不一致,最多的有多達一百項收費,少的也有十多項,所以收費公式不能寫死,應可以容納任意數目的操做數,任意數目的操做符。app

因而想到了逆波蘭表達式,逆波蘭表達式只須要簡單的入棧和出棧操做就能夠解決我所面臨的難題。測試

廢話很少說,直接上代碼,一看便知:ui

package reversePolishDemo;

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

/**
 * 逆波蘭表達式測試
 */
public class ReversePolish {    
     private final static ConcurrentHashMap<String, Integer> priority = new ConcurrentHashMap<String, Integer>();
     
     static {
            priority.put( "+", 0);
            priority.put( "-", 0);
            priority.put( "*", 1);
            priority.put( "/", 1);
     }
     
     // 逆波蘭表達式計算時所用的棧
     private Stack<Object> reversePolishStack = new Stack<Object>();
     // 存儲操做符
     private Stack<String> operatorStack = new Stack<String>(); 
     
     // 正常的中綴表達式,如3*(1+2)
     private String formular;
     
     /**
      * 參數是正常的中綴表達式,如3*(1+2)
      * */
     public ReversePolish(String formular){
            assert(formular != null);
            this. formular = formular.replace( " ", ""); // 去除全部空格
     }

     public String getFormular() {
            return formular;
     }

     public void setFormular(String formular) {
            this. formular = formular;
     }
     /**計算,返回結果*/
     public Integer calc(){
           List<Object> rpFormular = resolveFormular();
           Integer result = 0;
           
            for(Object obj : rpFormular){
                 if(obj instanceof Integer){
                      reversePolishStack.push((Integer) obj);
                } else {
                     String op = (String) obj;
                     Integer i = (Integer)reversePolishStack.pop();
                     Integer j = (Integer)reversePolishStack.pop();
                     
                      if(op.equals( "+")){
                           result = j + i;
                     } else if(op.equals( "-")){
                           result = j - i;
                     } else if(op.equals( "*")){
                           result = j * i;
                     } else {
                           result = j / i;
                     }
                     
                      reversePolishStack.push(result);
                }
           }
           
           
            return (Integer) reversePolishStack.pop();
     }
     
     public void testResolveFormular(){
           List<Object> rpFormular = resolveFormular();
            for(Object o : rpFormular){
                System. out.print(o + " ");
           }
           
     }
     
     /**
      * 將正常的中綴表達式轉換成逆波蘭表達式
      * */
     private List<Object> resolveFormular(){
            // 先切分formular,找出全部數字和運算符
            char[] array = formular.toCharArray();
            // 存放切分後的中綴表達式
           List<String> splitList = new ArrayList<String>();
           
            // 臨時存儲轉換後的解析後的後綴 formular
           List<Object> rpFormular = new ArrayList<Object>();           
           
           StringBuilder digitBuilder = new StringBuilder();
           
            for( int i = 0; i < array. length; i++){
                 if(Character. isDigit(array[i])){
                     digitBuilder.append(array[i]);
                } else {
                      if(digitBuilder.length() > 0){
                          splitList.add(digitBuilder.toString());
                           digitBuilder.delete(0, digitBuilder.length());
                     }
                     
                     splitList.add(array[i] + "");                   
                }
           }
           
            if(digitBuilder.length() > 0){
                splitList.add(digitBuilder.toString());
           }
           
            for(String s : splitList){
                Integer num = null;
                
                 try {
                     num = Integer. parseInt(s);
                } catch (Exception e) {
                }
                
                 if(num != null){      // 若是是數字,加入rpFormular列表
                     rpFormular.add(num);
                } else {    // 若是是運算符
                      if( operatorStack.isEmpty() || s.equals("(")){ // 若是運算符Stack爲空或者是左括號,壓入運算符棧
                            operatorStack.push(s);
                     } else {    // 若是運算符Stack不爲空                        
                           String top = operatorStack.peek(); //獲取棧頂元素,但不彈出棧頂元素
                           Integer topPriority = priority.get(top);   // 獲取棧頂運算符優先級

                            if(topPriority != null){    // 若是棧頂不是左括號
                                 // 若是運算符是右括號
                                 if(s.equals( ")")){
                                      while( true){     // 依次彈出運算符棧的棧頂元素,直到左括號被彈出爲止
                                           String element = operatorStack.pop();
                                           
                                           if(element.equals( "(")){
                                                 break;
                                           } else {
                                                rpFormular.add(element);
                                           }
                                     }
                                     
                                } else if( priority.get(s) <= topPriority){   //或者優先級低於或等於棧頂運算符優先級
                                      while( priority.get(s) <= topPriority){
                                          rpFormular.add( operatorStack.pop()); 
                                           
                                           if( operatorStack.empty()){
                                                 break;
                                           }
                                           topPriority = priority.get(operatorStack .peek());                                        
                                     }
                                      operatorStack.push(s);
                                } else {    // 若是s的優先級大於棧頂運算符的優先級,壓入運算符棧
                                      operatorStack.push(s);
                                }
                           } else {    // 若是棧頂是左括號,壓入運算符棧
                                 operatorStack.push(s);
                           }                          
                     }
                }
           }
           
            while(! operatorStack.empty()){
                rpFormular.add( operatorStack.pop());
           }
           
            return rpFormular;
           
     }
     
     public static void main(String[] args) {
           ReversePolish polish = new ReversePolish("9+(3-1)*3+10/2" );
           
           System. out.println(polish.calc());
     }
     
     
}

輸出結果:this

20
code

相關文章
相關標籤/搜索