字符串表达式的计算java版本

来源:互联网 发布:2017年网络赚钱新项目 编辑:程序博客网 时间:2024/04/28 07:02
package expressiontree;
import java.util.Stack;
/*
 * yy
 * 输入字符串表达式 输出计算结果
 * 写了将近2个小时,这个逻辑真是醉了
 * 目前只能接受整数,如果想要实现浮点数 则需要增加一个判读字符是浮点数的函数,其他的函数不变
 * */


public class MyCalculator {




private Stack<String> operatorNumber=new Stack<String>();//操作数栈
private Stack<Character> operatorStack=new Stack<Character>();//操作符栈


public MyCalculator() {
operatorStack.push('#');//操作符栈的栈底是#符号
}



public double calcaulate(String expression){
if("".equalsIgnoreCase(expression)||expression==null)return Double.MAX_VALUE;
char[] array=expression.toCharArray();
for(int i=0;i<array.length;i++){
if(Character.isDigit(array[i])){
operatorNumber.push(String.valueOf(array[i]));//表达式的当前值是数字,则直接压入到操作数栈中
}else{
if(operatorStack.peek()=='(' && array[i]!=')'){
   operatorStack.push(array[i]);
continue;
}else if(operatorStack.peek()=='(' && array[i]==')'){
operatorStack.pop();
continue;
}
boolean judje=compare(String.valueOf(operatorStack.peek()),String.valueOf(array[i]));
if(judje){
char op=operatorStack.pop();
String v1=operatorNumber.pop();
String v2=operatorNumber.pop();
operatorNumber.push(this.calculate(v2, v1, op));
i=i-1;
}else{
operatorStack.push(array[i]);
}
}
}
while(operatorStack.peek()!='#'){
if(operatorStack.peek()=='('||operatorStack.peek()==')'){
operatorStack.pop();
continue;
}
char op=operatorStack.pop();
String v1=operatorNumber.pop();
String v2=operatorNumber.pop();
operatorNumber.push(this.calculate(v1, v2, op));
}
return Double.valueOf(operatorNumber.pop());
}

/** 
     * 比较运算符等级 
     * @param peek 栈顶的元素 
     * @param cur  当前字符串的元素
     * @return 
     * 优先级的顺序是(  * \ +-)
     */  
    public  boolean compare(String peek, String cur){
    if("(".equals(peek)&& ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur)||"#".equals(cur)||")".equals(cur))){
    return true;
    }else if("*".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur)||"#".equals(cur)||")".equals(cur))){  
            return true;  
        }else if("/".equals(peek) && ("/".equals(cur) || "*".equals(cur) ||"+".equals(cur) ||"-".equals(cur)||"#".equals(cur))||")".equals(cur)){  
            return true;  
        }else if("+".equals(peek) && ("+".equals(cur) || "-".equals(cur)||"#".equals(cur)||")".equals(cur))){  
            return true;  
        }else if("-".equals(peek) && ("+".equals(cur) || "-".equals(cur)||"#".equals(cur)||")".equals(cur))){  
            return true;  
        }
        return false;  
    }  
//
/**
* 按照给定的算术运算符做计算
* @param firstValue
* @param secondValue
* @param currentOp
* @return
*/
private String calculate(String firstValue, String secondValue,char currentOp) {
String result = "";
switch (currentOp) {
case '+':
result = String.valueOf(ArithHelper.add(firstValue, secondValue));
break;
case '-':
result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
break;
case '*':
result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
break;
case '/':
result = String.valueOf(ArithHelper.div(firstValue, secondValue));
break;
}
return result;
}

/**
* 判断是否为算术符号
* @param c
* @return
*/
private boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '('
|| c == ')';
}

public static void main(String[] args) {
MyCalculator c=new MyCalculator();
System.out.println(c.calcaulate("(3*2)-(1*5)+(1+1)*2+(3*4)+3"));//20.0
}

}

package expressiontree;


public class ArithHelper {
// 默认除法运算精度
      private static final int DEF_DIV_SCALE = 16;
  
      // 这个类不能实例化
      private ArithHelper() {
      }
  
    /**
      * 提供精确的加法运算。
      * 
      * @param v1 被加数
      * @param v2 加数
      * @return 两个参数的和
      */
 
     public static double add(double v1, double v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
         java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
         return b1.add(b2).doubleValue();
    }
     
    public static double add(String v1, String v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
         java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
         return b1.add(b2).doubleValue();
     }
 
    /**
      * 提供精确的减法运算。
      * 
      * @param v1 被减数
      * @param v2 减数
      * @return 两个参数的差
      */
 
     public static double sub(double v1, double v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
         java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
         return b1.subtract(b2).doubleValue();
     }
     
     public static double sub(String v1, String v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
        java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
         return b1.subtract(b2).doubleValue();
     }
 
     /**
      * 提供精确的乘法运算。
      * 
      * @param v1
      *            被乘数
      * @param v2
      *            乘数
      * @return 两个参数的积
      */
 
     public static double mul(double v1, double v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
         java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
         return b1.multiply(b2).doubleValue();
     }
     
     public static double mul(String v1, String v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
         java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
         return b1.multiply(b2).doubleValue();
     }
 
     /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
      * 
      * @param v1
      *            被除数
      * @param v2
      *            除数
      * @return 两个参数的商
      */
 
     public static double div(double v1, double v2) {
         return div(v1, v2, DEF_DIV_SCALE);
     }
     
     public static double div(String v1, String v2) {
         java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
         java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
         return b1.divide(b2, DEF_DIV_SCALE, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
     }
 
     /**
      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
      * 
      * @param v1 被除数
      * @param v2 除数
      * @param scale 表示表示需要精确到小数点以后几位。
      * @return 两个参数的商
      */
 
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
       java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
       java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }
 
    /**
     * 提供精确的小数位四舍五入处理。
     * 
     * @param v 需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
 
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
        java.math.BigDecimal b = new java.math.BigDecimal(Double.toString(v));
        java.math.BigDecimal one = new java.math.BigDecimal("1");
        return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    
    public static double round(String v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
        }
        java.math.BigDecimal b = new java.math.BigDecimal(v);
        java.math.BigDecimal one = new java.math.BigDecimal("1");
        return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

0 0