最近在作一个知识产权的项目,被知识产权各类复杂的收费方式搞得烦死。因而想写一个通用的费用计算方式,操做人员能够在后台为每一个国家各类不一样的知识产权产品设订价格计算公式,系统调用公式便可算出结果,这样也方便之后增长其余国家的知识产权产品,方便设订价格。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