|
五个函数实现支持常用数学函数的四则运算表达式计算器,支持嵌套( )改变运算优先级,函数调用采用[ ],函数参数也支持表达式嵌套,目前支持的函数如下(p为参数):
sin[p] cos[p] tan[p] sinh[p] cosh[p] tanh[p] asin[p] acos[p] atan[p] abs[p] floor[p] ceil[p] sqrt[p] log[p] ln[p] exp[p] pow[p0, p1] mod[p0, p1]。
望大家帮忙测试哈有否错误,谢谢!
#include<iostream>
#include<cmath>
#include<vector>
#include<string>
#include<iterator>
using namespace std;
const float angle_radian = 0.017453292519943295769236907684886f; //角度到弧度转换率
const float radian_angle = 57.324840764331210191082802547771f; //弧度到角度转换率
//转换字符串到double
double str_double(const char* p);
//匹配圆括号
long match_round_bracket(const char* exp, long pos);
//匹配方括号
long match_square_bracket(const char* exp, long pos);
//函数计算
double function(const char* f, const char* params);
//计算器
double calculator(const std::string& expression);
//转换字符串到double
double str_double(const char* p)
{
if(NULL==p)return 0;
char zhengshu[64]={0};
char xiaoshu[32]={0};
bool bLoop=true;
bool bDecimal=false; //小数点
bool bNegative=false; //负数
long iz=0; //整数位数计数器
long ix=0; //小数位数计数器
while(0!=*p)
{
switch(*p)
{
case '0':
if(!bDecimal)
{
if(0!=iz)zhengshu[iz++]=*p;
}
else xiaoshu[ix++]=*p;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if(!bDecimal)zhengshu[iz++]=*p;
else xiaoshu[ix++]=*p;
break;
case '.':
if(!bDecimal)bDecimal=true;
else bLoop = false;
break;
case '-':
if(!bNegative)bNegative=true;
else bLoop = false;
break;
default:break;
}
if(!bLoop || iz>=64 || ix>=32)break;
++p;
}
if(0==iz && 0==ix)return 0;
//求整数部分
double q = 1;//权数
double result = 0;//结果
while(iz-->0)
{
switch(zhengshu[iz])
{
case '1':
result+=q;
break;
case '2':
result+=2*q;
break;
case '3':
result+=3*q;
break;
case '4':
result+=4*q;
break;
case '5':
result+=5*q;
break;
case '6':
result+=6*q;
break;
case '7':
result+=7*q;
break;
case '8':
result+=8*q;
break;
case '9':
result+=9*q;
break;
default: break;
}
q*=10;
}
//求小数部分
q=0.1;
long k = 0;
while(k<ix)
{
switch(xiaoshu[k])
{
case '1':
result+=q;
break;
case '2':
result+=2*q;
break;
case '3':
result+=3*q;
break;
case '4':
result+=4*q;
break;
case '5':
result+=5*q;
break;
case '6':
result+=6*q;
break;
case '7':
result+=7*q;
break;
case '8':
result+=8*q;
break;
case '9':
result+=9*q;
break;
default: break;
}
q*=0.1;
++k;
}
if(bNegative)return -result;
else return result;
}
//匹配圆括号
long match_round_bracket(const char* exp, long pos)
{
if(NULL==exp || '('!=*(exp+pos))return -1;
long count = 1;
++pos;
while(0!=*(exp+pos))
{
switch(*(exp+pos))
{
case '(':
++count;
break;
case ')':
--count;
break;
default:break;
}
if(0==count)return pos;
++pos;
}
return -1;
}
//匹配方括号
long match_square_bracket(const char* exp, long pos)
{
if(NULL==exp || '['!=*(exp+pos))return -1;
long count = 1;
++pos;
while(0!=*(exp+pos))
{
switch(*(exp+pos))
{
case '[':
++count;
break;
case ']':
--count;
break;
default:break;
}
if(0==count)return pos;
++pos;
}
return -1;
}
//函数计算
double function(const char* f, const char* params)
{
if(NULL==f || NULL==params)return 0;
double p[8]={0};
long start=0, end=0, count=0;
char tmp[128]={0};
std::string s(f);
if("sin"==s || "cos"==s || "tan"==s
|| "sinh"==s || "cosh"==s || "tanh"==s
|| "asin"==s || "acos"==s || "atan"==s
|| "abs"==s || "floor"==s || "ceil"==s
|| "sqrt"==s || "log"==s || "ln"==s || "exp"==s)p[count++]=calculator(params);
else
{
while(0!=*(params+end))
{
if(','==*(params+end))
{
if(end-start>127)return 0;
::memcpy(tmp, (params+start), end-start);
tmp[end-start]=0;
if(count>7)return 0;
p[count++]=calculator(tmp);
start=end+1;
}
++end;
}
if(end-start>127)return 0;
::memcpy(tmp, (params+start), end-start);
tmp[end-start]=0;
if(count>7)return 0;
p[count++]=calculator(tmp);
}
///*
cout<<f<<ends;
cout<<"参数个数为:"<<count<<endl;
for(long i=0; i<count; ++i)cout<<p<<ends;
cout<<endl<<endl;
//*/
if("sin"==s)return sin(p[0]*angle_radian);
else if("cos"==s)return cos(p[0]*angle_radian);
else if("tan"==s)return tan(p[0]*angle_radian);
else if("sinh"==s)return sinh(p[0]*angle_radian);
else if("cosh"==s)return cosh(p[0]*angle_radian);
else if("tanh"==s)return tanh(p[0]*angle_radian);
else if("asin"==s)return asin(p[0])*radian_angle;
else if("acos"==s)return acos(p[0])*radian_angle;
else if("atan"==s)return atan(p[0])*radian_angle;
else if("abs"==s)return fabs(p[0]);
else if("floor"==s)return floor(p[0]);
else if("ceil"==s)return ceil(p[0]);
else if("sqrt"==s)return sqrt(p[0]);
else if("log"==s)return log(p[0]);
else if("ln"==s)return log10(p[0]);
else if("exp"==s)return exp(p[0]);
else if("pow"==s)return pow(p[0], p[1]);
else if("mod"==s)return fmod(p[0], p[1]);
else return 0;
}
//计算器
double calculator(const std::string& expression)
{
std::string s = expression;
std::string strNumber;
std::string strFunc;
std::vector<double> params;
std::vector<double> nums;
std::vector<char> ops;
double result = 0;
double tmp = 0;
long p=-1;
for(long i = 0; i < s.size(); ++i)
{
switch(s)
{
case '(':
{
if(-1==(p=match_round_bracket(s.c_str(), i)))return 0;
tmp = calculator(s.substr(i+1,p-i-1));
nums.push_back(tmp);
i=p;
break;
}
case '[':
{
if(strFunc.empty() || -1==(p=match_square_bracket(s.c_str(), i)))return 0;
tmp=function(strFunc.c_str(), s.substr(i+1,p-i-1).c_str());
nums.push_back(tmp);
i=p;
break;
}
case '*':
case '/':
case '+':
case '-':
{
if(('-'==s && 0==i && nums.empty())
|| ('-'==s && (!nums.empty()) && (!nums.empty()) && nums.size()==ops.size()))//处理负号
{
strNumber+="-";
break;
}
else
{
if(!strNumber.empty())nums.push_back(str_double(strNumber.c_str()));
ops.push_back(s);
strNumber="";
break;
}
}
case ',':
break;
case '0':
if(!strNumber.empty())strNumber+='0';
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
strNumber+=s;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
strFunc+=s;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
strFunc+=s+32;
break;
default:break;
}
}
if(!strNumber.empty())nums.push_back(str_double(strNumber.c_str()));
///*
cout<<"所有操作数:"<<ends;
copy(nums.begin(), nums.end(), ostream_iterator<double, char>(cout, " "));
cout<<endl;
cout<<"所有运算符:"<<ends;
copy(ops.begin(), ops.end(), ostream_iterator<char, char>(cout, " "));
cout<<endl;
//*/
if(ops.size()+1!=nums.size())return 0;
for(i=0; i<ops.size();)
{
switch(ops)
{
case '*':
{
nums *= nums[i+1];
nums.erase(nums.begin()+i+1);
ops.erase(ops.begin()+i);
break;
}
case '/':
{
nums /= nums[i+1];
nums.erase(nums.begin()+i+1);
ops.erase(ops.begin()+i);
break;
}
default: ++i;
}
}
if(ops.size()+1!=nums.size())return 0;
i=0;
while(nums.size()>1)
{
switch(ops)
{
case '+':
{
nums += nums[i+1];
nums.erase(nums.begin()+i+1);
ops.erase(ops.begin()+i);
break;
}
case '-':
{
nums -= nums[i+1];
nums.erase(nums.begin()+i+1);
ops.erase(ops.begin()+i);
break;
}
}
}
return nums[0];
}
int main()
{
char ep[] = "sqrt[pow[1.1,asin[sin[5*(3*(4+5)-9)]]]]";
cout<<ep<<"="<<calculator(ep)<<endl<<endl;
return 0;
}
运行结果如下:
|
|