java 代码
- import java.math.BigDecimal;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Stack;
- import java.util.StringTokenizer;
- public class Expression {
- public static void main(String[] args) {
- String expres = "c*d+(((a+67.32)+(c-39))/d+10)";
- // expres = "11*13+(((13+67.32)+(13-39))/56+23)";
- HashMap variables = new HashMap();
- variables.put("a",new BigDecimal("10"));
- variables.put("b",new BigDecimal("20"));
- variables.put("c",new BigDecimal("30"));
- variables.put("d",new BigDecimal("40"));
- Expression calc = new Expression(variables,expres);
- // calc = new Ccl(null,expres);
- double resut = calc.getResult().doubleValue();
- System.out.println(" Expression = "+expres);
- calc.printVariables();
- System.out.println(" Result = " + resut);
- }
- //----------
- private String expression;
- private HashMap operators = new HashMap();
- {
- operators.put("+", "1");
- operators.put("-", "1");
- operators.put("/", "2");
- operators.put("*", "2");
- operators.put("(", "0");
- }
- private Context ctx;
- public Expression(HashMap vars,String expr) {
- ctx = new Context(vars);
- expression = expr;
- }
- public BigDecimal getResult() {
- //infix to Postfix
- String pfExpr = infixToPostFix(toVaviable(expression));
- //build the Binary Tree
- Expressions rootNode = buildTree(pfExpr);
- //Evaluate the tree
- return rootNode.evaluate(ctx).setScale(2,BigDecimal.ROUND_HALF_UP);
- }
- private NonTerminalExpression getNonTerminalExpression(
- String operation,
- Expressions l,
- Expressions r) {
- if (operation.trim().equals("+")) {
- return new AddExpression(l, r);
- }
- if (operation.trim().equals("-")) {
- return new SubtractExpression(l, r);
- }
- if (operation.trim().equals("*")) {
- return new MultiplyExpression(l, r);
- }
- if (operation.trim().equals("/")) {
- return new DivExpression(l, r);
- }
- return null;
- }
- private String toVaviable(String str){
- char var = 'z';
- StringBuffer tmp = new StringBuffer();
- StringTokenizer st = new StringTokenizer(str, "+-*/()", true);
- String ss = null;
- while (st.hasMoreElements()) {
- ss = st.nextToken();
- if(isDigital(ss)){
- ctx.assign((var)+"",ss);
- tmp.append((var)+"");
- var--;
- }else{
- tmp.append(ss);
- }
- // System.out.println(ss);
- }
- return tmp.toString();
- }
- private String infixToPostFix(String str) {
- Stack s = new Stack();
- String pfExpr = "";
- String tempStr = "";
- String expr = str.trim();
- for (int i = 0; i < str.length(); i++) {
- String currChar = str.substring(i, i + 1);
- if ((isOperator(currChar) == false)
- && (!currChar.equals("("))
- && (!currChar.equals(")"))) {
- pfExpr = pfExpr + currChar;
- }
- if (currChar.equals("(")) {
- s.push(currChar);
- }
- //for ')' pop all stack contents until '('
- if (currChar.equals(")")) {
- tempStr = (String) s.pop();
- while (!tempStr.equals("(")) {
- pfExpr = pfExpr + tempStr;
- tempStr = (String) s.pop();
- }
- tempStr = "";
- }
- //if the current character is an
- // operator
- if (isOperator(currChar)) {
- if (s.isEmpty() == false) {
- tempStr = (String) s.pop();
- String strVal1 = (String) operators.get(tempStr);
- int val1 = new Integer(strVal1).intValue();
- String strVal2 = (String) operators.get(currChar);
- int val2 = new Integer(strVal2).intValue();
- while ((val1 >= val2)) {
- pfExpr = pfExpr + tempStr;
- val1 = -100;
- if (s.isEmpty() == false) {
- tempStr = (String) s.pop();
- strVal1 = (String) operators.get(tempStr);
- val1 = new Integer(strVal1).intValue();
- }
- }
- if ((val1 < val2) && (val1 != -100))
- s.push(tempStr);
- }
- s.push(currChar);
- } //if
- } // for
- while (s.isEmpty() == false) {
- tempStr = (String) s.pop();
- pfExpr = pfExpr + tempStr;
- }
- return pfExpr;
- }
- private Expressions buildTree(String expr) {
- Stack s = new Stack();
- for (int i = 0; i < expr.length(); i++) {
- String currChar = expr.substring(i, i + 1);
- if (isOperator(currChar) == false) {
- Expressions e = new TerminalExpression(currChar);
- s.push(e);
- } else {
- Expressions r = (Expressions) s.pop();
- Expressions l = (Expressions) s.pop();
- Expressions n = getNonTerminalExpression(currChar, l, r);
- s.push(n);
- }
- } //for
- return (Expressions) s.pop();
- }
- private boolean isDigital(String str) {
- if (!isOperator(str) && !ctx.checkKey(str) && !isComma(str))
- return true;
- return false;
- }
- private boolean isComma(String str) {
- if ((str.equals("("))
- || (str.equals(")")))
- return true;
- return false;
- }
- private boolean isOperator(String str) {
- if ((str.equals("+"))
- || (str.equals("-"))
- || (str.equals("*"))
- || (str.equals("/")))
- return true;
- return false;
- }
- public void printVariables(){
- this.ctx.print();
- }
- } // End of class
- class Context {
- private HashMap varList = new HashMap();
- public void assign(String var, String value) {
- varList.put(var, new BigDecimal(value));
- }
- public BigDecimal getValue(String var) {
- BigDecimal tmp;
- if(varList.get(var) == null){
- tmp = new BigDecimal(var);
- }else{
- tmp = (BigDecimal) varList.get(var);
- }
- // System.out.println(var+ " "+tmp.doubleValue());
- return tmp;
- }
- public boolean checkKey(String var){
- return varList.get(var) == null?false:true;
- }
- public void print(){
- Object ob ;
- for(Iterator it = varList.keySet().iterator();it.hasNext();){
- ob = it.next();
- System.out.println(ob+" = "+varList.get(ob));
- }
- }
- public Context(HashMap vars) {
- if(vars !=null)
- varList = vars;
- }
- }
- class TerminalExpression implements Expressions {
- private String var;
- public TerminalExpression(String v) {
- var = v;
- }
- public BigDecimal evaluate(Context c) {
- return c.getValue(var);
- }
- }
- interface Expressions {
- public BigDecimal evaluate(Context c);
- }
- abstract class NonTerminalExpression implements Expressions {
- private Expressions leftNode;
- private Expressions rightNode;
- public NonTerminalExpression(Expressions l, Expressions r) {
- setLeftNode(l);
- setRightNode(r);
- }
- public void setLeftNode(Expressions node) {
- leftNode = node;
- }
- public void setRightNode(Expressions node) {
- rightNode = node;
- }
- public Expressions getLeftNode() {
- return leftNode;
- }
- public Expressions getRightNode() {
- return rightNode;
- }
- } // NonTerminalExpression
- class AddExpression extends NonTerminalExpression {
- public BigDecimal evaluate(Context c) {
- return getLeftNode().evaluate(c).add(getRightNode().evaluate(c));
- }
- public AddExpression(Expressions l, Expressions r) {
- super(l, r);
- }
- } // AddExpression
- class SubtractExpression extends NonTerminalExpression {
- public BigDecimal evaluate(Context c) {
- return getLeftNode().evaluate(c).subtract(getRightNode().evaluate(c));
- }
- public SubtractExpression(Expressions l, Expressions r) {
- super(l, r);
- }
- } // SubtractExpression
- class MultiplyExpression extends NonTerminalExpression {
- public BigDecimal evaluate(Context c) {
- return getLeftNode().evaluate(c).multiply(getRightNode().evaluate(c));
- }
- public MultiplyExpression(Expressions l, Expressions r) {
- super(l, r);
- }
- } //
- class DivExpression extends NonTerminalExpression {
- public BigDecimal evaluate(Context c) {
- return getLeftNode().evaluate(c).divide(getRightNode().evaluate(c),4,BigDecimal.ROUND_HALF_UP);
- }
- public DivExpression(Expressions l, Expressions r) {
- super(l, r);
- }
- } //