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();
}
}
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();
}
}