这个算法,应该是我到大学写的第一个递归,其实要点就是那个括号总是不匹配,解决方法就是自己写个计数器。
主文件:
#include<cstdio>
#include<string>
#include<iostream>
#include<cmath>
#include<strstream>
using namespace std;
string LastErrorText="";
string LastText="";
extern string sonsin(string AnalyseCal,int Addr);
extern string soncos(string AnalyseCal,int Addr);
extern string sontan(string AnalyseCal,int Addr);
extern string sonsqrt(string AnalyseCal,int Addr);
extern string sonlong(string AnalyseCal,int Addr);
extern string sonabs(string AnalyseCal,int Addr);
extern string Minus(string AnalyseCal,int Addr);
extern string Plus(string AnalyseCal,int Addr);
extern string Minuss(string AnalyseCal,int Addr);
extern string Pluss(string AnalyseCal,int Addr);
extern string Como(string AnalyseCal,int Addr);
string CalChar[]= {"sin","cos","tan","sqrt","long","abs","(","+","*","/","-"};
string (*f[])(string,int)= {sonsin,soncos,sontan,sonsqrt,sonlong,sonabs,Como,Plus,Pluss,Minuss,Minus};
extern double todouble(string obj);
double Calculate(string CalculateText){
int Addr,sum=0;
if(LastText==CalculateText){LastErrorText="Unlimited Loop 1.";return 0;}
string AnalyseCal=CalculateText+"";
for(int NowAddr=0;NowAddr!=11;NowAddr++){
Addr=-1;
while((Addr=AnalyseCal.find(CalChar[NowAddr],Addr+1))!=-1){
AnalyseCal=(*f[NowAddr])(AnalyseCal,Addr);
sum++;
if(sum>=100000){
LastErrorText="Unlimited Loop 2.";
break;
}
}
}
return todouble(AnalyseCal);
}
void read(int args,char* argv[]){
string Command="";
Command=argv[1];
FILE *fp;
if(Command=="-c"||Command=="-C"){
LastErrorText="Calculate Success!";
Command="";
for(int i=2;i!=args;i++){
Command+=argv[i];
cout<<Calculate(Command)<<endl<<LastErrorText<<endl;
}
}
if(Command=="-i"||Command=="-I"){
if((fp=fopen(argv[2],"r"))==NULL){printf("Warning:Cannot open file:%s",argv[2]);return;}
char ch=fgetc(fp);
Command="";
LastErrorText="Calculate Success!";
while(ch!=EOF){
if(ch!=' ')Command+=ch;
ch=fgetc(fp);
}
cout<<Calculate(Command)<<endl<<LastErrorText<<endl;
}
}
int main(int args,char* argv[]){
if(args<2)return 0;
read(args,argv);
return 0;
}
解释特殊函数的文件:
#include<string>
#include<strstream>
#include<cmath>
using namespace std;
strstream CoMath;
extern string LastErrorText;
extern double Calculate(string CalculateText);
int findComo(string Text,int BaseInt){
int Balance=1,i;
for(i=BaseInt+1;i!=Text.length();i++){
if(Text.at(i)=='('){Balance++;}
if(Text.at(i)==')'){Balance--;}
if(!Balance)break;
}
if(Balance)LastErrorText="Error:À¨ºÅ²»Æ¥Åä!";
return i;
}
string getComoText(string Text,int BaseInt){
int Addr=findComo(Text,BaseInt);
if(~Addr)return Text.substr(BaseInt+1,Addr-BaseInt-1);
return "";
}
double todouble(string obj){
CoMath.clear();
CoMath<<obj;
double Temp=0;
CoMath>>Temp;
return Temp;
}
string tostring(double obj){
CoMath.clear();
CoMath<<obj;
string Temp;
CoMath>>Temp;
return Temp;
}
string sonsin(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(sin(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
return AnalyseCal;
}
string soncos(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(cos(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
return AnalyseCal;
}
string sontan(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(tan(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
return AnalyseCal;
}
string sonabs(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(abs(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
return AnalyseCal;
}
string sonsqrt(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(sqrt(Calculate(getComoText(AnalyseCal.substr(Addr+4),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+4)+1);
return AnalyseCal;
}
string sonlong(string AnalyseCal,int Addr){
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(log(Calculate(getComoText(AnalyseCal.substr(Addr+4),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+4)+1);
return AnalyseCal;
}
string Plus(string AnalyseCal,int Addr){
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))+Calculate(AnalyseCal.substr(Addr+1)));
return AnalyseCal;
}
string Minus(string AnalyseCal,int Addr){
if(Addr==0)
AnalyseCal="0"+AnalyseCal;
else
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))-Calculate(AnalyseCal.substr(Addr+1)));
return AnalyseCal;
}
string Pluss(string AnalyseCal,int Addr){
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))*Calculate(AnalyseCal.substr(Addr+1)));
return AnalyseCal;
}
string Minuss(string AnalyseCal,int Addr){
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))/Calculate(AnalyseCal.substr(Addr+1)));
return AnalyseCal;
}
string Como(string AnalyseCal,int Addr){
if(Addr&&AnalyseCal.at(Addr-1)>='0'&&AnalyseCal.at(Addr-1)<='9')
AnalyseCal=AnalyseCal.substr(0,Addr)+"*"+AnalyseCal.substr(Addr);
else
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(Calculate(getComoText(AnalyseCal.substr(Addr),0)))+AnalyseCal.substr(findComo(AnalyseCal,Addr)+1);
return AnalyseCal;
}
/*
if(CalChar[NowAddr]=="sin")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(sin(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
else if(CalChar[NowAddr]=="cos")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(cos(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
else if(CalChar[NowAddr]=="tan")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(tan(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
else if(CalChar[NowAddr]=="abs")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(fabs(Calculate(getComoText(AnalyseCal.substr(Addr+3),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+3)+1);
else if(CalChar[NowAddr]=="sqrt")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(sqrt(Calculate(getComoText(AnalyseCal.substr(Addr+4),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+4)+1);
else if(CalChar[NowAddr]=="long")
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(log(Calculate(getComoText(AnalyseCal.substr(Addr+4),0))))+AnalyseCal.substr(findComo(AnalyseCal,Addr+4)+1);
else if(CalChar[NowAddr]=="+")
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))+Calculate(AnalyseCal.substr(Addr+1)));
else if(CalChar[NowAddr]=="*")
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))*Calculate(AnalyseCal.substr(Addr+1)));
else if(CalChar[NowAddr]=="/")
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))/Calculate(AnalyseCal.substr(Addr+1)));
else if(CalChar[NowAddr]=="-"){
if(Addr==0)
AnalyseCal="0"+AnalyseCal;
else
AnalyseCal=tostring(Calculate(AnalyseCal.substr(0,Addr))-Calculate(AnalyseCal.substr(Addr+1)));
}
else if(CalChar[NowAddr]=="("){
if(Addr&&AnalyseCal.at(Addr-1)>='0'&&AnalyseCal.at(Addr-1)<='9')
AnalyseCal=AnalyseCal.substr(0,Addr)+"*"+AnalyseCal.substr(Addr);
else
AnalyseCal=AnalyseCal.substr(0,Addr)+tostring(Calculate(getComoText(AnalyseCal.substr(Addr),0)))+AnalyseCal.substr(findComo(AnalyseCal,Addr)+1);
}
sum++;
*/