Answer类:
package calculator;
public class Answer
{
private double x;
private boolean key;
private int ei;
public Answer(double i,boolean j,int k)
{
x=i;
key=j;
ei=k;
}
public void answer(double a)
{
x=a;
}
public void setKey(boolean a)
{
key=a;
}
public void setEi(int a)
{
ei=a;
}
public double getAnswer(){return x;}
public boolean getKey(){return key;}
public int getEi(){return ei;}
public void passer(Answer a,Answer b)
{
key=(a.getKey()&b.getKey());
if(!(a.getKey())) ei=a.getEi();
else if(!b.getKey()) ei=b.getEi();
else ei=0;
}
public void passer(Answer a)
{
key=a.getKey();
ei=a.getEi();
}
}
主程序:
package calculator;
import java.util.Scanner;
public class calculator{
public static Answer analyze(String a)//主分析方法,分析算式结构,利用递归,最终目的是返回一个数值
{
int k[];
k=new int[128];
int i;
int x;
int flag;
String a1,a2;
char operator,c;
Answer an=new Answer(0,true,0);
boolean fushu;
x=0;
a1="";
a2="";
operator=' ';
c=' ';
for(i=0;i<=a.length()-1;i++)//对算式进行分层标记,括号内的权重增加,数字为1,运算符为0
{
fushu=false;
c=a.charAt(i);
if(i==0) fushu=true;
if(c=='(') {x++; fushu=true;}
if(((c>='0')&&(c<='9'))||(c=='-')&&(fushu)||(c=='.')||/*(c=='^')||*/((c>='a')&(c<='z'))) k[i]=x+1;
else k[i]=x;
if(a.charAt(i)==')') x--;
}
if(x!=0){an.answer(0);an.setKey(false);an.setEi(102);return(an);} //括号不匹配报错
flag=-1;
for(i=0;i<=a.length()-1;i++)//找加减号
{
c=a.charAt(i);
if((k[i]==0)&&((c=='+')||(c=='-')))
{
flag=i;
}
}
if(flag>=0)
{
c=a.charAt(flag);
a1=a.substring(0,flag);
a2=a.substring(flag+1,a.length());
operator=c;
an=plusminus(a1,a2,operator);
return(an);
}
flag=-1;
for(i=0;i<=a.length()-1;i++)//找乘除号
{
c=a.charAt(i);
if((k[i]==0)&&((c=='*')||(c=='/'))) flag=i;
}
if(flag>=0)
{
c=a.charAt(flag);
a1=a.substring(0,flag);
a2=a.substring(flag+1,a.length());
operator=c;
an=multidiv(a1,a2,operator);
return(an);
}
flag=-1;
for(i=0;i<=a.length()-1;i++)//找乘方符号
{
c=a.charAt(i);
if(c=='^') flag=i;
}
if(flag>=0)
{
a1=a.substring(0,flag);
a2=a.substring(flag+1,a.length());
an=mypow(a1,a2);
return(an);
}
c=a.charAt(0);
if(((c>='a')&(c<='z'))||((c>='A')&(c<='Z'))) {an=hanshu(a);return(an);}//计算函数
if(c=='(') //去括号
{
a=a.substring(1,a.length()-1);
an=analyze(a);
return(an);
}
an.answer(Double.parseDouble(a));
return(an);
}
public static Answer plusminus(String a1, String a2, char op)//加减法方法。
{
Answer an=new Answer(0,true,0);
Answer a1n=new Answer(0,true,0);
Answer a2n=new Answer(0,true,0);
a1n=analyze(a1);
a2n=analyze(a2);
an.passer(a1n,a2n);
if (an.getKey())
{
if(op=='+') an.answer(a1n.getAnswer()+a2n.getAnswer());
else if(op=='-') an.answer(a1n.getAnswer()-a2n.getAnswer());
}
else an.answer(0);
return(an);
}
public static Answer multidiv(String a1, String a2, char op)//乘除法方法
{
Answer an=new Answer(0,true,0);
Answer a1n=new Answer(0,true,0);
Answer a2n=new Answer(0,true,0);
a1n=analyze(a1);
a2n=analyze(a2);
an.passer(a1n,a2n);
if (an.getKey())
{
if(op=='*') an.answer(a1n.getAnswer()*a2n.getAnswer());
else if(op=='/')
if(a2n.getAnswer()==0)
{an.answer(0);an.setKey(false);an.setEi(101);}
else an.answer(a1n.getAnswer()/a2n.getAnswer());
}
else an.answer(0);
return(an);
}
public static Answer mypow(String a1, String a2)//乘方计算
{
Answer an=new Answer(0,true,0);
Answer a1n=new Answer(0,true,0);
Answer a2n=new Answer(0,true,0);
a1n=analyze(a1);
a2n=analyze(a2);
an.passer(a1n,a2n);
if (an.getKey())
{
if((a1n.getAnswer()<0)&&((a2n.getAnswer()-(int)a2n.getAnswer())!=0))
{an.answer(0);an.setKey(false);an.setEi(301);}
else if ((a1n.getAnswer()==0)&&(a2n.getAnswer()==0))
{an.answer(0);an.setKey(false);an.setEi(302);}
else an.answer(Math.pow(a1n.getAnswer(),a2n.getAnswer()));
}
else an.answer(0);
return(an);
}
public static void errorinformation(int a)
{
switch(a)
{
case 101: System.out.println("错误:除数为零,请自行计算极限。");break;
case 102: System.out.println("错误:括号不匹配。");break;
case 201: System.out.println("错误:函数越界——定义域大于等于0。");break;
case 211: System.out.println("错误:括号里什么都没有。");break;
case 202: System.out.println("错误:函数越界——定义域大于等于-1小于等于1。");break;
case 301: System.out.println("错误:仅能进行实数域范围内的计算。");break;
case 302: System.out.println("错误:零的零次是什么,我不明白。");break;
}
}
public static Answer hanshu(String a)//对于形如xxx(a)的函数的处理 现在还待解决多元函数和形如x^y的处理方式
{
Answer an=new Answer(0,true,0);
Answer num=new Answer(0,true,0);
int i,flag;
char c;
String name,number;
c=' ';
flag=1;
number="";
name="";
for(i=1;i<=a.length()-1;i++)
{
c=a.charAt(i);
if(c=='(') {flag=i;break;}
}
name=a;
if (flag>1)
{
name=a.substring(0,flag);
if(flag!=a.length()-2)
{
number=a.substring(flag+1,a.length()-1);
num=analyze(number);
}
else {an.answer(0);an.setKey(false);an.setEi(211);return(an);}
}
switch(name)
{
case "abs":an.answer(Math.abs(num.getAnswer()));an.passer(num);break;
case "sin":an.answer(Math.sin(num.getAnswer()));an.passer(num);break;
case "cos":an.answer(Math.cos(num.getAnswer()));an.passer(num);break;
case "tan":an.answer(Math.tan(num.getAnswer()));an.passer(num);break;
case "sqrt":
if (num.getAnswer()>=0) {an.answer(Math.tan(num.getAnswer()));an.passer(num);}
else {an.setEi(201);an.setKey(false);an.answer(0);}
break;
case "ln":if (num.getAnswer()>=0) {an.answer(Math.log(num.getAnswer()));an.passer(num);}
else {an.setEi(201);an.setKey(false);an.answer(0);}
break;
case "log":if (num.getAnswer()>=0) {an.answer(Math.log10(num.getAnswer()));an.passer(num);}
else {an.setEi(201);an.setKey(false);an.answer(0);}
break;
case "arcsin":if((num.getAnswer()>=-1)&(num.getAnswer()<=1))
{
an.answer(Math.asin(num.getAnswer()));
an.passer(num);
}
else {an.setEi(202);an.setKey(false);an.answer(0);}
break;
case "arccos":if((num.getAnswer()>=-1)&(num.getAnswer()<=1))
{
an.answer(Math.acos(num.getAnswer()));
an.passer(num);
}
else {an.setEi(202);an.setKey(false);an.answer(0);}
case "arctan":an.answer(Math.atan(num.getAnswer()));an.passer(num);break;
case "PI":an.answer(Math.PI);break;
case "pi":an.answer(Math.PI);break;
case "E":an.answer(Math.E);break;
case "e":an.answer(Math.E);break;
}
return(an);
}
public static void main(String[] args) //没什么意义的主程序
{
Scanner ipt=new Scanner(System.in);
String a,k;
int ei;
Answer an=new Answer(0,true,0);
while(true)
{
System.out.print("请输入算式:");
a=ipt.nextLine();
an=analyze(a);
if (an.getKey()) System.out.println("="+an.getAnswer());
else {ei=an.getEi();errorinformation(ei);}
System.out.print("是否退出?(Y退出,任意键回车继续):");
k=ipt.nextLine();
if(k.length()>0) if(k.charAt(0)=='Y') break;
}
}
}