数据结构和算法, 我还没明白

永远的C

博客园 首页 新随笔 联系 订阅 管理
package cross.pauliuyou.calculator.base;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.Vector;

/**
*
*
@author 刘优
*
@version 1.1
*
*
*
*
*/

public class CalculateUnit {
    Vector
<BigDecimal> numbers;
    Vector
<Character> operators;
   
   
public CalculateUnit(Vector<BigDecimal> nums,Vector<Character> ops) {
        numbers
= nums;
        operators
= ops;
       
int j = 0;
       
for (int i = 0; i < operators.size(); i++) {
           
if (getOpObjNum(operators.get(i)) == 1) {
                numbers.add(i
+j,numbers.get(i+j));
                j
++; } } } public BigDecimal calculate() throws CalculateException {
       
int [] levels = new int[operators.size()];
       
for (int i = 0; i < levels.length; i++) {
            levels[i]
= i;
        }
        sort(levels,operators);
       
for (int i = 0; i < levels.length; i++) {
           
int opPos = levels[i];
           
char op = operators.get(opPos);
           
int numPos = opPos;
           
int nullPos = -1;
           
int nullNum = 0;
           
boolean move = true;
           
for (int j = opPos; j >=0; j--) {
               
char tm = operators.get(j);
               
if (tm != '0') {
                    move
= false;
                }
               
else {
                   
if (!move) {
                        nullPos
= j;
                    }
                    nullNum
++;
                }
            }
           
if (nullPos != -1 && move) {
                numPos
= nullPos;
            }
           
else {
                numPos
-= nullNum;
            }
           
int objnum = this.getOpObjNum(op);
           
switch (objnum) {
               
case 1:
               
case 2:
                    BigDecimal left
= numbers.get(numPos);
                    BigDecimal right
= numbers.get(numPos + 1);
                    BigDecimal rs
= cal(left,right,op);
                    numbers.remove(numPos
+ 1);
                    numbers.remove(numPos);
                    numbers.add(numPos,rs);
                    operators.remove(opPos);
                    operators.add(opPos,
'0');
                   
break;
               
case 3:
               
default:
                   
break;
            }
           
        }
       
return numbers.get(0);
    }
   
   
protected static BigDecimal jie(BigDecimal x) throws CalculateException {
       
if (x.compareTo(BigDecimal.ZERO) == -1 || x.toString().indexOf(".") != -1) {
           
throw new CalculateException("负数或小数不允许算阶乘");
        }
        BigInteger result
= BigInteger.ONE;
        BigInteger num
= new BigInteger(x.intValue() + "");
       
while (num.compareTo(BigInteger.ONE) == 1) {
            result
= result.multiply(num);
            num
= num.subtract(BigInteger.ONE);
        }
       
return new BigDecimal(result);
    }
   
private static BigDecimal sqrt(BigDecimal x) throws CalculateException {
       
if (x.compareTo(BigDecimal.ZERO) == -1) {
           
throw new CalculateException("负数不能开平方");
           
        }
       
return new BigDecimal(Math.sqrt(x.doubleValue()) + "");
    }
   
public static BigDecimal cal(BigDecimal x,BigDecimal y,char op) throws CalculateException {
       
//System.out.println("cal : " + x + op + y);
        switch (op) {
       
case '+' :
           
return x.add(y);
       
case '-' :
           
return x.subtract(y);
       
case '*' :
           
return x.multiply(y);
       
case '/' :
           
if (y.compareTo(BigDecimal.ZERO) == 0) {
               
throw new CalculateException("不允许除零!");
            }
           
return x.divide(y,MathContext.DECIMAL64);
       
case '!' :
           
return jie(x);
       
case 's' :
           
return sqrt(x);
       
case 'p' :
           
return x.pow(y.intValue());
           
       
default :
           
throw new CalculateException("不支持的运算符 :" + op);
           
        }
       
    }
   
private int getOpObjNum(char c) {
       
if (c == '!' || c == 's') {
           
return 1;
        }
       
if (c == 'p') {
           
return 2;
        }
       
if (c == '*' || c == '/') {
           
return 2;
        }
       
if (c == '+' || c == '-') {
           
return 2;
        }
       
return 0;
    }
   
private int getLevel(char c) {
       
if (c == 'p') {
           
return 70;
        }
       
else if (c == '!' || c == 's') {
           
return 60;
        }
       
else if (c == '/') {
           
return 50;
        }
       
else if (c == '*') {
           
return 49;
        }
       
else if (c == '-') {
           
return 40;
        }
       
else if (c == '+') {
           
return 39;
        }
       
       
return 0;
    }
   
private void sort(int [] in,Vector<Character> ops) {
       
for (int i = 0; i < ops.size(); i++) {
           
int t = getLevel(ops.get(in[i]));
           
int pos = i;
           
for (int j = i + 1; j < ops.size(); j++) {
               
int t2 = getLevel(ops.get(in[j]));
               
if (t2 > t) {
                    t
= t2;
                    pos
= j;
                }
            }
           
if (pos != i) {
               
int ttt = in[i];
                in[i]
= in[pos];
                in[pos]
= ttt;
            }
        }
    }
   
public double oldCalculate(Vector<BigDecimal> numbers,Vector<Character> operators) throws CalculateException {
        BigDecimal d
= null;
       
while (operators.size() > 0) {
           
for (int i = 0; i < operators.size(); i++) {
               
char c = operators.get(i);
               
if (getLevel(c) == 0)
               
if (c == '*' || c == '/') {
                    d
= cal(numbers.get(i),numbers.get(i + 1),c);
                    numbers.remove(i
+ 1);
                    numbers.remove(i);
                    numbers.add(i,d);
                    operators.remove(i);
                   
break;
                }
               
boolean hasMutli = false;
               
for (int j = i + 1; j < operators.size(); j++) {
                   
if (operators.get(j) == '*' || operators.get(j) == '/') {
                        hasMutli
= true;
                       
break;
                    }
                }
               
if (!hasMutli) {
                    d
= cal(numbers.get(i),numbers.get(i + 1),operators.get(i));
                    numbers.remove(i
+ 1);
                    numbers.remove(i);
                    numbers.add(i,d);
                    operators.remove(i);
                   
break;
                }
            }
        }
       
return numbers.get(0).doubleValue();
       
    }
   
public String toString() {
       
return "num : " + numbers.toString() + "\nops : " + operators.toString();
    }
   
}
posted on 2008-07-09 20:53  Pauliuyou  阅读(581)  评论(1编辑  收藏  举报