/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author 黄攀
* 实现科学计算器的接口
*/
public class Calculate implements ICalculate{
//设置表达式字符串
public String appendchar(String aa,StringBuffer tt)
{
tt.append(aa);
return new String(tt);
}
//根据括号来分解表达式字符串
public String countall(String tt)
{
StringBuffer mm=new StringBuffer(tt);
Boolean errorstop=true;
int i, j, m=0, n=0;
for( ; m!= -1 ; ) //开始对括号内容经行优先处理
{ m= -1; n=-2;
for(i=0; i<mm.length(); i++) //找最里面的前半个括号
if( mm.charAt(i)== '(' ) { m=i; }
for(n=-1,j=m+1;j<mm.length();j++) //在前半个括号找到后,再找后半个括号
if(mm.charAt(j)== ')') { n=j; break;}
if(m<0&&n<0) break; //如没有找到括号,则跳出次部分
else
{
if(m*n<0||m>=n-1||m>0&&Iscountnum(mm.charAt(m-1))==0||n<mm.length()-1&&
Iscountnum( mm.charAt(n+1))==0 ) //如找到:半个括号,无内容的括号,前半个括号一个字符是数字或者是小数点,后一个括号的下一个字符是数字或者是小数点都提示一下错误
{
mm.setLength(0); //强行清空字符变量的内容,使此方法此次计算的返回值为空
errorstop=false;
break;}
else
{
mm.replace(m,n+1,counting(mm.substring(m+1,n))); //把括号的部分用计算的结果来取代
}
}
}
if(errorstop) //进行最后一级运算(即无括号计算)
{
mm.replace(0,mm.length(),counting(mm.substring(0,mm.length())));
}
return(mm.toString( ) );
}
//将运算符转化为相应的数值方法
public int Iscountnum(Character hh)
{
String mm=new String("+-×÷%.()");
int i,t=-1;
for(i=0;i<mm.length();i++)
if(mm.charAt(i)==hh)
{ t=i;break;}
return(t+1);
}
//计算无括号下的表达式字符串
public String counting(String qq)
{
StringBuffer nn=new StringBuffer(qq);
Double numgroup[]=new Double[20];
numgroup[0]=Double.MIN_VALUE;
StringBuffer result=new StringBuffer(Double.toString(numgroup[0]));
Boolean cancounting0=true;
Boolean cancounting1=true;
Boolean cancounting2=true;
Boolean cancounting3=true;
Character countnum[]=new Character[20];
int i,j,t=0;
if(Iscountnum(nn.charAt(0))>2&&Iscountnum(nn.charAt(0))<7||Iscountnum(nn.charAt(nn.length()-1))<7&& Iscountnum(nn.charAt(nn.length()-1))>0) //如此部分的第一个字符是小数点或是“×”、 “÷”、 “%”其中之一,此部分的最后一个字符不是以数字结尾都是非法数学表达式
{ cancounting0=false;
}
if(cancounting0)
{
for(j=2;j<nn.length();j++)
{ if(Iscountnum(nn.charAt(j-2))!=0&&Iscountnum(nn.charAt(j-1))!=0&&Iscountnum(nn.charAt(j))!=0 )
//如出现连续三个数学计算(包括小数点)是非法数学表达式
{ cancounting1=false;
}
}
for( i=0, j=1; j<nn.length(); j++) //校监此部分的数学的表达式是否可以计算
{
if(0<Iscountnum(nn.charAt(j-1))&&Iscountnum(nn.charAt(j-1))<6&&Iscountnum(nn.charAt(j))==0)
//记录前一个数学计算符的位置
{ i=j; }
if(nn.charAt(j)=='.'&&Iscountnum(nn.charAt(j-1))!=0||nn.charAt(j-1)=='.'&&Iscountnum(nn.charAt(j))!=0 )
//如小数点的前面或后面不是数字,则提示以下信息
{
cancounting2=false;
break; }
if(0<Iscountnum(nn.charAt(j-1))&&Iscountnum(nn.charAt(j-1))<6&&Iscountnum(nn.charAt(j))==1)
//出现“++”,“—+”,“×+”,“÷+”,“%+”情况删除“+”即可
{ nn.deleteCharAt(j);
j=0; //经操作后次数学表达式改变,要从头开始
}
else if(2<Iscountnum(nn.charAt(j-1))&&Iscountnum(nn.charAt(j-1))<6&&Iscountnum(nn.charAt(j))==2)
//出现 “×—”,“÷ —”,“%—”情况把“—”移到前一个操作符后面
{ nn.deleteCharAt(j);
nn.insert(i,new Character('-'));
j=0; }
else if(Iscountnum(nn.charAt(j-1))==1&&Iscountnum(nn.charAt(j))==2)
//出现“+—” 把“+”号删掉
{ nn.deleteCharAt(j-1);
j=0;}
else if(Iscountnum(nn.charAt(j-1))==2&&Iscountnum(nn.charAt(j))==2)
//出现“——” 把“——”号用“+”代替
{ nn.replace(j-1,j+1,new String("+"));
j=0;}
else if(Iscountnum(nn.charAt(j-1))*Iscountnum(nn.charAt(j))!=0)
//出现其他连有两个数学符号的情况是不正确的,则有以下错误消息
{ cancounting3=false;
break; }
}
}
if(cancounting0&&cancounting1&&cancounting2&&cancounting3)
//现在把校对的数学表达式划分为数字和计算符两部分,并分别储存在两个不同的数组中
{
for(i=0,j=1;j<nn.length();j++)
{
if(Iscountnum(nn.charAt(j))!=0&&nn.charAt(j)!='.')
{ numgroup[t]=Double.parseDouble(nn.substring(i,j));
countnum[t]=new Character(nn.charAt(j));
i=j+1;
t++;}
}
numgroup[t]=Double.parseDouble(nn.substring(i,j) );
for(i=0;i<t;i++) //现在将数字数组参考计算符数组进行计算
if(2<Iscountnum(countnum[i])&&Iscountnum(countnum[i])<6) //首先计算× ÷ %运算符
{switch(Iscountnum(countnum[i]))
{ case 3: numgroup[i]=numgroup[i]*numgroup[i+1];break;
case 4: numgroup[i]=numgroup[i]/numgroup[i+1];break;
case 5: numgroup[i]=numgroup[i]%numgroup[i+1];break;}
for(j=i;j<t-1;j++) //把计算后的数字和参与计算的计算符用其后的覆盖
{ numgroup[j+1]=numgroup[j+2];
countnum[j]=countnum[j+1];}
if(i<t-1)
numgroup[j+1]=numgroup[j+2];
i--;
t--;
}
for(i=0;i<t;i++)
if(0<Iscountnum(countnum[i])&&Iscountnum(countnum[i])<3) //现在计算+ -运算符
{ switch(Iscountnum(countnum[i]))
{case 1: numgroup[i]=numgroup[i]+numgroup[i+1];break;
case 2: numgroup[i]=numgroup[i]-numgroup[i+1];break;}
for(j=i;j<t-1;j++) //同理,把计算后的数字和参与计算的计算符用其后的覆盖
{numgroup[j+1]=numgroup[j+2];
countnum[j]=countnum[j+1];}
if(i<t-1)
numgroup[j+1]=numgroup[j+2];
i--;
t--;
}
result=new StringBuffer(Double.toString(numgroup[0]));
}
if(numgroup[0]==Double.MIN_VALUE) //考虑非法数学表达式的返回值
{ result.setLength(0); //设置次返回值为空
}
return(result.toString());
}
}