游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1933|回复: 0

五个函数实现支持常用数学函数的四则运算表达式计算器

[复制链接]

45

主题

157

帖子

169

积分

注册会员

Rank: 2

积分
169
QQ
发表于 2009-11-7 18:41:00 | 显示全部楼层 |阅读模式
五个函数实现支持常用数学函数的四则运算表达式计算器,支持嵌套( )改变运算优先级,函数调用采用[ ],函数参数也支持表达式嵌套,目前支持的函数如下(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;
}
运行结果如下:

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-18 05:00

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表