package Calculator;
import java.math.BigDecimal;
public class CalculatorClass {
private String formula;
private static int EXACT_VALUE;
private int cou=0;//该常量保存计算结果的精确位数信息,默认为6
public void setEXACT_VALUE(int i){
EXACT_VALUE=i;
}
public CalculatorClass(){
EXACT_VALUE=6;
}
public CalculatorClass(int i){
setEXACT_VALUE(i);
}
public void setFormula(String formula){ //可在这个传入formula属性的方法中检查传入参数是否合法
this.formula=formula;
}
public String toCount(String formula){ //该方法提取formula中的子公式,传给方法toSimpleformulat()来计算,再将返回结果重新组织,再重复操作,直到得出答案
if(!check(formula)){
return "输入的格式错误,请重输";
}
setFormula(formula);
while(formula.indexOf('+')!=-1||formula.indexOf('-')!=-1||
formula.indexOf('*')!=-1||formula.indexOf('/')!=-1){ //该循环退出的条件是formula内含有所有运算符都没有的状况。当然,如果结果为负,在循环内有退出的命令
String simpleFormula; //记录子公式的变量
String simpleResult=""; //记录toCount()计算的结果
if(formula.indexOf('(')!=-1||formula.indexOf(')')!=-1){ //提取子公式,先取出小括号内的公式给toSimpleformula()计算
int start=0;
int end=1;
for(int i=0;i<formula.length();i++){
if(formula.charAt(i)=='('){
start=i;
}
if(formula.charAt(i)==')'){
end=i;
break;
}
}
simpleFormula=formula.substring(start+1, end);//将子公式赋给simpleFormula并在后边传给toSimpleformula()
simpleResult=toSimpleformula(simpleFormula);//保存计算结果
formula=formula.substring(0, start)+simpleResult+formula.substring(end+1,formula.length());//重新组织公式字符串,等待下次使用
}else{
if(formula.matches("^[-]?[0-9]+[\\.]?[0-9]*$")){//如果formula为数值,则表示计算得出最后答案,非常高兴地break退出循环
break;
}
formula=toSimpleformula(formula); //运算这行代码的情形是formula里面没括号了。。。
}
}
return formula;//向调用该方法的语句返回计算的结果
}
public String toSimpleformula(String simpleformula){//前面一直在说的计算无括号四则运算的函数
System.out.println("第"+(++cou)+"步:"+simpleformula);
int sfa=simpleformula.length();//用变量sfs记录字符串的长度,
String[] numCache=new String[sfa];//numCache将在后面按顺序保存所有的数值,包括负数
char[] opertorCache=new char[sfa];//opertorCache将在后卖弄按顺序保存所有的运算符
int countOp=0;//在后面做opertorCache的下标,最后用来表示opertorCache的数组长度
int countNu=0;//numCache的。。。同上
String xx="";//后面的循环中xx叠加一串串数值
for(int i=0;i<sfa;i++){//大概说下:循环一遍simpleformula字符串,将运算符+-*/ 与数字分开保存到各自数组中去
if(i!=0&&(simpleformula.charAt(i)=='+' ||simpleformula.charAt(i)=='-'
||simpleformula.charAt(i)=='*'||simpleformula.charAt(i)=='/')){
opertorCache[countOp++]=simpleformula.charAt(i);//
numCache[countNu++]=xx;
xx="";
if((i<sfa-1)&&simpleformula.charAt(i+1)=='-'){
xx="-";
i+=1;
continue;
}
}else{
xx+=simpleformula.charAt(i);
}
if(i==sfa-1){
numCache[countNu++]=xx;
}
}
BigDecimal[] BigDecnumCache=new BigDecimal[countNu];//将numCache中的数值都赋给BigDecnumCache数组,BigDecimal用来做最后的计算保证结果的准确性
for(int i=0;i<countNu;i++){
BigDecnumCache[i]=new BigDecimal(numCache[i]);
}
for(int i=0;i<countOp;i++){//先循环遍历一遍,把乘除先算了,
if(opertorCache[i]=='*'){
BigDecnumCache[i+1]=BigDecnumCache[i+1].multiply(BigDecnumCache[i]);
BigDecnumCache[i]=BigDecimal.valueOf(0);
if(i!=0&&opertorCache[i-1]=='-'){
opertorCache[i]='-';
}else{
opertorCache[i]='+';
}
}
if(opertorCache[i]=='/'){
BigDecnumCache[i+1]=BigDecnumCache[i].divide(BigDecnumCache[i+1], EXACT_VALUE,BigDecimal.ROUND_HALF_UP);
BigDecnumCache[i]=BigDecimal.valueOf(0);
if(i!=0&&opertorCache[i-1]=='-'){
opertorCache[i]='-';
}else{
opertorCache[i]='+';
}
}
}
for(int i=0;i<countOp;i++){//最后计算加减
if(opertorCache[i]=='-'){
BigDecnumCache[i+1]=BigDecnumCache[i].subtract(BigDecnumCache[i+1]);
}
if(opertorCache[i]=='+'){
BigDecnumCache[i+1]=BigDecnumCache[i+1].add(BigDecnumCache[i]);
}
}
return BigDecnumCache[BigDecnumCache.length-1].toString();//返回字符创类型的结果,方便后面的公式再组织
}
public boolean check(String formula){
int kuohaoCount=0;
String[] fuhaoStr=formula.split("[0-9\\.\\(\\)]");
for(int i=0;i<fuhaoStr.length;i++){
if(fuhaoStr[i].length()>1 && fuhaoStr[i].charAt(1)!='-'){
System.out.println("运算符格式错误");
return false;
}
}
for(int i=0;i<formula.length();i++){
char x=formula.charAt(i);
if(x==','||x<40 || x>57){
System.out.println("输入的字符错误");
return false;
}
if(x=='('){
kuohaoCount++;
}else if(x==')'){
kuohaoCount--;
}
if(kuohaoCount<0){
return false;
}
}
return true;
}
}