关闭

二叉树计算包含函数的中缀表达式

687人阅读 评论(0) 收藏 举报

        二叉树计算中缀表达式,支持科学计数法,支持前导正负号,支持指数运算符“^”,支持括号,支持函数,具有错误检查。以字符串形式输入。

 

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
#include <float.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
   #include <windows.h>
   #include <malloc.h>
#else
   #include <alloc.h>
#endif

#ifndef STRICT
   #define STRICT 1
#endif

/* 判断双精度double变量是否溢出的宏,参数x为双精度变量 */
#define inf_double(x) (((*((unsigned long *)&(x)) == 0) && (*((unsigned long *)&(x) + 1) == 0x7ff00000)) ? 1 : 0)
/* 判断双精度double变量是否是未定义结果的宏,参数x为双精度变量 */
#define ind_double(x) (((*((unsigned long *)&(x)) == 0) && (*((unsigned long *)&(x) + 1) == 0xfff80000)) ? 1 : 0)
/* 判断单精度float变量是否溢出的宏,参数x为单精度变量 */
#define inf_float(x) ((*((unsigned long *)&(x)) == 0x7f800000) ? 1 : 0)
/* 判断单精度float变量是否是未定义结果的宏,参数x为单精度变量 */
#define ind_float(x) ((*((unsigned long *)&(x)) == 0xffc00000) ? 1 : 0)
#define filldoublewithinf(x) (*((unsigned long *)&(x)) = 0x0, *(((unsigned long *)&(x) + 1)) = 0x7ff00000)
#define filldoublewithind(x) (*((unsigned long *)&(x)) = 0x0, *(((unsigned long *)&(x) + 1)) = 0xfff80000)

#ifdef _WIN32
   #define checkdouble_(x) ((!_finite(x)) || (_isnan(x)))
#else
   #define checkdouble_(x) (inf_double(x) || ind_double(x))
#endif
#define checkdouble(x)  if (checkdouble_(x)) return 0
#define inf_double_return(x)  if (checkdouble_(x)) return(x)
#define checkdoublereturn(x)  if (checkdouble_(x)) return 0; else return 1

#define lchild2 lchild->lchild
#define lchild3 lchild2->lchild
#define rchild2 rchild->rchild
#define rchild3 rchild2->rchild
#define next2   next->next
#define next3   next2->next

#define E     2.7182818284590452353602874713526624977572
#define PI    3.1415926535897932384626433832795028841971
#define PI_2  1.5707963267948966192313216916397514420985
#define SQRT2 1.4142135623730950488016887242096980785696

#define SIGNMARK     0x80
#define BRACKETSMARK 0x40
#define FUNCTIONMARK 0x20
#define BRAC_FUNMARK (BRACKETSMARK | FUNCTIONMARK)
#define MAXBUFFERLEN 1024
#define MAXBRACKETSDEPTH 10000

#define CHECKBRACKETSDEPTH 1

/* 宏:直接计算括号内只有一步计算的表达式,例如(12.34+56.78)
#define DIRECTCASIMPLE 1
*/

typedef void(* vfunptr)(void);
typedef double(* dfunptr1)(double);
typedef double(* dfunptr2)(double, double);
typedef double(* dfunptr3)(double, double, double);

typedef struct tagbintree
{
 char op;
 unsigned char mark;
 double fvalue;
 void *vdataptr;  /* 用来处理数组类型数据 */
 struct tagbintree *lchild;
 struct tagbintree *rchild;
}bintree;

typedef struct tagparanode
{
 struct tagbintree *bintreenode;
 struct tagparanode *next;
}paranode, *List;

/* 用于表达式中函数计算
   函数节点前增加一个前驱,函数节点作为其右子树
   mark设函数标记,op保存函数参数个数:链表参数的记为-1 */
typedef struct tagfunnode
{
 vfunptr funptr;           /* 通用无类型函数指针 */
 char *szfunname;          /* 保存函数名称的缓冲区 */
 struct tagparanode *para; /* 保存函数参数的链表 */
}funnode;

typedef double(* lfunptr)(const List);

#define Alloctree ((bintree *)malloc(sizeof(bintree)))
#define Allocparanode ((paranode *)malloc(sizeof(paranode)))
#define Allocfunnode ((funnode *)malloc(sizeof(funnode)))

char getoperatorlevel(char op);
int isoperator(unsigned char c);
double caltree(const bintree *node);
void preorderdistree(const bintree *node);
void postorderdistree(const bintree *node);
void destorytree(bintree **node);
void destroyparalist(paranode *head);
bintree *appendnode(bintree **node, char op, double value, char sign);
int getfunptr(const char *szfunname, vfunptr *funp);
int isconstant(const char *sznum, double *variable);
int isvariable(const char *sznum, double *variable);
int checknum(const char *sznum);
int islegaldoublenum(const char *sznum);
int bracketsmatchingcheck(const char *szsrc);
long getmaxbracketsdepth(const char *szsrc);
double strtodouble(const char *sznum);
bintree *createtree(const char *szexpress);
bintree *createtree_(const char **szexpress, long *para);
int checkexpression(const char *szexpress);
int checkexpression_(const char **szexpress, int colon, long *para);
double calfun1(const funnode *node);
double calfun2(const funnode *node);
double calfun3(const funnode *node);
double cot(double x);
double sec(double x);
double csc(double x);
double sgn(double x);
double logr(double b, double x);
double max_(const List head);
double min_(const List head);
double mean(const List head);
double sum(const List head);
double squaresum(const List head);
double cubicsum(const List head);
double mid3(double v1, double v2, double v3);
double iiif(const List head);
double iif(const bintree *condition, const bintree *truepart, const bintree *falsepart);
double nofun(const List head, unsigned long index);
#ifdef _WIN32
  void catcher(int sig);

  void catcher(int sig)
  {
   printf("divide by 0.\n");
  }

  int _matherr(struct _exception *e)
  {
   filldoublewithind(e->retval);

   return 1;
  }
#else
  void catcher(int sig, int type, int *reglist);

  void catcher(int sig, int type, int *reglist)
  {
   printf("divide by 0.\n");
  }

  int matherr(struct exception *e)
  {
   filldoublewithind(e->retval);

   return 1;
  }
#endif

int main(int argc, char *argv[], char *env[])
{
 char s[1000];
 bintree *root;

 signal(SIGFPE, SIG_IGN);  /* 将被零除信号设为忽略 */

 strcpy(s, "-1+2*3^-2^-2^-(1*(2+1)^-4^-1.4)");
 printf("%s\n", s);
 root = createtree(s);
 postorderdistree(root);
 printf("\n=%.10lf\n\n", caltree(root));
 destorytree(&root);

 strcpy(s, "((((-(11.86)-2)+54.89*(45.8)*54)*2)*-(-12.39+-(23^-pow(2,0.81))))*2^ -3 + 2^3^-0.3");
 printf("%s\n", s);
 root = createtree(s);
 postorderdistree(root);
 printf("\n=%.10lf\n\n", caltree(root));
 destorytree(&root);

 strcpy(s, "iif(3> 2, 0, 20) ? sin(PI): cos(PI_2)+ -1+mean(10 + pi*sqrt(12.890),max(12.34 , -90, 67.21) , 123.21) + fabs (-(1+sin(1+logr(10,190)))/cos(12)+sqrt(2)^2)");
 printf("%s\n", s);
 root = createtree(s);
 postorderdistree(root);
 printf("\n=%.10lf\n\n", caltree(root));
 destorytree(&root);

 strcpy(s, "0 ? 10: log(-max(12.34,5.6*1.2,3.45^2.1^-2.9,PI,logr(2,10)))");

 printf("%s\n", s);
 while(1)
  {
   printf("input expression(0 to end):");
   gets(s);

   if (s[0] == '0' && s[1] == '\0')
    break;

   if (bracketsmatchingcheck(s))
    {
     #ifdef CHECKBRACKETSDEPTH
       if (getmaxbracketsdepth(s) > MAXBRACKETSDEPTH)
        {
         printf("The brackets are too cpmplex.\n");
         continue;
        }
     #endif
     if (checkexpression(s))
      {
       if ((root = createtree(s)) != NULL)
        {
         postorderdistree(root);
         printf("\n=%.10lf\n", caltree(root));
         destorytree(&root);
        }
       else
        printf("Fails to create tree.");
      }
     else
      printf("Expression error.\n");
    }
   else
    printf("Brackets do not match.\n");
  }

 printf("\n");
 getch();
}

/*
*    名称: preorderdistree
*    功能: 前序遍历显示表达式树结构
*  返回值: 无返回值
*    参数: const bintree *node  指向要显示表达式树根节点的常指针
*/
void preorderdistree(const bintree *node)
{
 if (node != NULL)
  {
   if (node->mark & FUNCTIONMARK)
    {
     paranode const *p = (paranode const *)((funnode const *)node->rchild)->para;
     printf("%s( ", ((funnode const *)node->rchild)->szfunname);

     while(p)
      {
       postorderdistree(p->bintreenode);
       printf(p->next ? "," : ") ");
       p = p->next;
      }
    }
   else
    {
     if (node->op)
      printf("%c ", node->op);
     else
      printf("%5.3f ", node->fvalue);

     preorderdistree(node->lchild);
     preorderdistree(node->rchild);
    }
  }
}

/*
*    名称: postorderdistree
*    功能: 后序遍历显示表达式树结构
*  返回值: 无返回值
*    参数: const bintree *node  指向要显示表达式树根节点的常指针
*/
void postorderdistree(const bintree *node)
{
 if (node != NULL)
  {
   if (node->mark & FUNCTIONMARK)
    {
     paranode const *p = (paranode const *)((funnode const *)node->rchild)->para;
     printf("%s( ", ((funnode const *)node->rchild)->szfunname);

     while(p)
      {
       postorderdistree(p->bintreenode);
       printf(p->next ? "," : ") ");
       p = p->next;
      }
    }
   else
    {
     postorderdistree(node->lchild);
     postorderdistree(node->rchild);

     if (node->op)
      printf("%c ", node->op);
     else
      printf("%5.3f ", node->fvalue);
    }
  }
}

/*   名称: destorytree
*    功能: 销毁树
*  返回值: 无返回值
*    参数: bintree **node  指向要销毁树的根节点的二级指针
*/
void destorytree(bintree **node)
{
 if (*node == NULL)
  return;

 if ((*node)->mark & FUNCTIONMARK)  /* 销毁函数部分 */
  {
   funnode *p = (funnode *)(*node)->rchild;

   free(p->szfunname);
   destroyparalist(p->para);  /* 销毁函数参数链表部分 */
   free(p);
   free(*node);
   *node = NULL;
   return;
  }

 if ((*node)->lchild != NULL)
  destorytree(&(*node)->lchild);
 if ((*node)->rchild != NULL)
  destorytree(&(*node)->rchild);

 free(*node);
 *node = NULL;
}

/*   名称: destroyparalist
*    功能: 销毁函数参数链表
*  返回值: 无返回值
*    参数: paranode *head  函数参数链表头指针
*/
void destroyparalist(paranode *head)
{
 paranode *p;

 if (head == NULL)
  return;

 p = head->next;
 destorytree(&head->bintreenode);
 free(head);
 while(p)
  {
   head = p->next;

   destorytree(&p->bintreenode);
   free(p);
   p = head;
  }
}

/*   名称: appendnode
*    功能: 向表达式树添加节点
*  返回值: 添加成功 返回指向生成的新节点的指针,失败 返回 NULL
*    参数: bintree **node  指向表达式树根节点(已生成的非空节点)的二级指针
*          char op         运算符
*          double value    右操作数的值
*          char sign       右操作数符号(0:正,1:负)
*/
bintree *appendnode(bintree **node, char op, double value, char sign)
{
 bintree *nodeop;
 bintree *nodenum;

 if ((nodeop = Alloctree) == NULL)
  return NULL;

 nodeop->op = op;
 nodeop->mark = 0;

 if ((nodenum = Alloctree) == NULL)
  {
   free(nodeop);

   return NULL;
  }

 nodenum->op = 0;
 nodenum->mark = 0;
 if (sign == 0)
  {
   nodenum->fvalue = value;
   nodenum->lchild = NULL;
   nodenum->rchild = NULL;
  }
 else if (op == '^')  /* ^由符号位记录负号 */
  {
   nodenum->fvalue = value;
   nodenum->lchild = NULL;
   nodenum->rchild = NULL;
   nodeop->mark |= SIGNMARK;
  }
 else  /* 其他运算符右操作数的负号处理成0- */
  {
   nodenum->op = '-';
   if ((nodenum->lchild = Alloctree) == NULL)
    {
     free(nodeop);
     free(nodenum);

     return NULL;
    }
   nodenum->lchild->op = 0;
   nodenum->lchild->fvalue = 0;
   nodenum->lchild->mark = 0;
   nodenum->lchild2 = NULL;
   nodenum->lchild->rchild = NULL;

   if ((nodenum->rchild = Alloctree) == NULL)
    {
     free(nodeop);
     free(nodenum->lchild);
     free(nodenum);

     return NULL;
    }
   nodenum->rchild->op = 0;
   nodenum->rchild->fvalue = value;
   nodenum->rchild->mark = 0;
   nodenum->rchild->lchild = NULL;
   nodenum->rchild2 = NULL;
  }

 if (op == '^')  /* ^向右下穿透负指数项 */
  {
   bintree *rp;
   if (getoperatorlevel(op) == getoperatorlevel((*node)->op) && op != (*node)->op)
    {
     nodeop->lchild = *node;
     *node = nodeop;
    }
   else if (getoperatorlevel(op) < getoperatorlevel((*node)->op) || ((*node)->mark & BRACKETSMARK) || getoperatorlevel((*node)->op) == 0)
    {
     nodeop->lchild = *node;
     *node = nodeop;
    }
   else if (getoperatorlevel(op) > getoperatorlevel((*node)->op))
    {
     rp = *node;

     while(getoperatorlevel(op) > getoperatorlevel(rp->rchild->op) && (rp->rchild->mark & BRACKETSMARK) != BRACKETSMARK && getoperatorlevel(rp->rchild->op))
      {
       rp = rp->rchild;
      }
     if ((getoperatorlevel(op) == getoperatorlevel(rp->rchild->op) && op != rp->rchild->op) || (getoperatorlevel(op) < getoperatorlevel(rp->rchild->op) || (rp->rchild->mark & BRACKETSMARK) == BRACKETSMARK || getoperatorlevel(rp->rchild->op) == 0))
      {
       nodeop->lchild = rp->rchild;
       rp->rchild = nodeop;
       nodeop->rchild = nodenum;

       return nodeop;
      }

     nodeop->rchild = rp->rchild;  /* rp->rchild 第一项指数项 */
     while(op == nodeop->rchild->op)
      {
       if (nodeop->rchild->mark & BRACKETSMARK)
        break;

       if (nodeop->rchild->mark & SIGNMARK)
        rp = nodeop->rchild;

       nodeop->rchild = nodeop->rchild2;
      }

     nodeop->lchild = rp->rchild;
     rp->rchild = nodeop;
    }
   else
    {
     int te = 1;
     rp = nodeop->rchild = *node;

     while(op == nodeop->rchild->op)
      {
       if (nodeop->rchild->mark & BRACKETSMARK)
        break;

       if (nodeop->rchild->mark & SIGNMARK)
        {
         rp = nodeop->rchild;
         te = 0;
        }

       nodeop->rchild = nodeop->rchild2;
      }
     if (te)
      {
       nodeop->lchild = *node;
       *node = nodeop;
      }
     else
      {
       nodeop->lchild = rp->rchild;
       rp->rchild = nodeop;
      }
    }

   nodeop->rchild = nodenum;

   return nodeop;
  }

 /* 添加非指数运算符节点 */
 if (getoperatorlevel(op) > getoperatorlevel((*node)->op) && ((*node)->mark & BRACKETSMARK) != BRACKETSMARK && getoperatorlevel((*node)->op))
  {
   nodeop->rchild = *node;

   while(getoperatorlevel(op) > getoperatorlevel(nodeop->rchild2->op) && (nodeop->rchild2->mark & BRACKETSMARK) != BRACKETSMARK && getoperatorlevel(nodeop->rchild2->op))
    {
     nodeop->rchild = nodeop->rchild2;
    }
   nodeop->lchild = nodeop->rchild2;
   nodeop->rchild2 = nodeop;
  }
 else
  {
   nodeop->lchild = *node;
   *node = nodeop;
  }

 nodeop->rchild = nodenum;

 return nodeop;
}

/*   名称: getoperatorlevel
*    功能: 获取运算符级别(包括分隔符)
*  返回值: 返回运算符的级别
*    参数: char op  运算符
*
*    说明: 以查表方式获取
*          运算符中指数运算符^单独设最高级
*/
char getoperatorlevel(char op)
{
 #ifdef _WIN32
    static const char charactertype[384] =
 #else
          static char charactertype[384] =
 #endif
  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,64,64, 4, 2,64, 2, 0, 4, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0,64, 0, 1, 0, 1,64, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0};

 return charactertype[op + 128];
}

/*   名称: isoperator
*    功能: 识别字符是否为运算符
*  返回值: 是运算符返回级别值(非0),不是运算符返回0
*    参数: char c  欲识别字符
*
*    说明:没使用
*/
int isoperator(unsigned char c)
{
 if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '<' || c == '>' || c == '(' || c == ')' || c == ',' || c == '?' || c == ':')
  return 1;

 return 0;
}

/*   名称: cot
*    功能: 计算三角函数的余切函数
*  返回值: 以x为参数值的余切值;参数为INF或IND时直接返回
*    参数: double x  弧度表示的角
*/
double cot(double x)
{
 inf_double_return(x);

 return tan(PI_2 - x);
}

/*   名称: sec
*    功能: 计算三角函数的正割函数
*  返回值: 以x为参数值的正割值;参数为INF或IND时直接返回
*    参数: double x  弧度表示的角
*/
double sec(double x)
{
 inf_double_return(x);

 return 1 / cos(x);
}

/*   名称: csc
*    功能: 计算三角函数的余割函数
*  返回值: 以x为参数值的余割值;参数为INF或IND时直接返回
*    参数: double x  弧度表示的角
*/
double csc(double x)
{
 inf_double_return(x);

 return 1 / sin(x);
}

/*   名称: sgn
*    功能: 返回参数的符号
*  返回值: 参数 > 0 返回 1,参数 == 0 返回 0, 参数 < 0 返回 -1;参数为INF或IND时直接返回
*    参数: double x  双精度变量
*/
double sgn(double x)
{
 inf_double_return(x);

 if (x > 0)
  return 1;
 if (x < 0)
  return -1;

 return 0;
}

/*   名称: logr
*    功能: 计算以b为底的x的对数
*  返回值: 成功 返回计算结果,不成功 返回IND值;参数中有INF或IND时直接返回
*    参数: double b  底数
*          double x  真数
*
*    说明:b > 0 且b ≠ 1,x > 0
*/
double logr(double b, double x)
{
 inf_double_return(x);
 inf_double_return(b);

 if (x < 0 || b < 0 || b == 1)
  {
   filldoublewithind(x);
   return x;
  }

 x = log(x);
 inf_double_return(x);
 b = log(b);
 inf_double_return(b);

 return x / b;
}

/*   名称: max_
*    功能: 返回参数中的最大值
*  返回值: 返回最大值;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double max_(const List head)
{
 double v;
 double v1;
 register List p = head;

 v = caltree(p->bintreenode);
 inf_double_return(v);

 p = p->next;
 while(p)
  {
   v1 = caltree(p->bintreenode);
   inf_double_return(v1);

   if (v1 > v)
    v = v1;
   p = p->next;
  }

 return v;
}

/*   名称: min_
*    功能: 返回参数中的最小值
*  返回值: 返回最小值;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double min_(const List head)
{
 double v;
 double v1;
 register List p = head;

 v = caltree(p->bintreenode);
 inf_double_return(v);

 p = p->next;
 while(p)
  {
   v1 = caltree(p->bintreenode);
   inf_double_return(v1);

   if (v1 < v)
    v = v1;
   p = p->next;
  }

 return v;
}

/*   名称: mean
*    功能: 返回参数的算术平均数
*  返回值: 返回算术平均数;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double mean(const List head)
{
 double sum;
 register long n = 1L;
 register List p = head;

 sum = caltree(p->bintreenode);
 inf_double_return(sum);

 p = p->next;
 while(p)
  {
   sum += caltree(p->bintreenode);
   inf_double_return(sum);

   n++;
   p = p->next;
  }

 return sum / n;
}

/*   名称: mid3
*    功能: 返回三个数中的中间值
*  返回值: 返回中间值;参数中有INF或IND时直接返回
*    参数: double v1  第一个数
*          double v2  第二个数
*          double v3  第三个数
*/
double mid3(double v1, double v2, double v3)
{
 inf_double_return(v1);
 inf_double_return(v2);
 inf_double_return(v3);

 if (v1 > v2)
  {
   if (v2 > v3)
    return v2;
   else
    return (v1 > v3) ? v3 : v1;
  }
 else
  {
   if (v3 > v2)
    return v2;
   else
    return (v1 > v3) ? v1 : v3;
  }
}

/*   名称: sum
*    功能: 返回参数的和
*  返回值: 返回和;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double sum(const List head)
{
 double v;
 double sum;
 register List p = head;

 v = caltree(p->bintreenode);
 inf_double_return(v);
 sum = v;
 inf_double_return(sum);

 p = p->next;
 while(p)
  {
   v = caltree(p->bintreenode);
   inf_double_return(v);
   sum += v;
   inf_double_return(sum);
   p = p->next;
  }

 return sum;
}

/*   名称: squaresum
*    功能: 返回参数的平方和
*  返回值: 返回平方和;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double squaresum(const List head)
{
 double v;
 double sumofsquare;
 register List p = head;

 v = caltree(p->bintreenode);
 inf_double_return(v);
 sumofsquare = v * v;
 inf_double_return(sumofsquare);

 p = p->next;
 while(p)
  {
   v = caltree(p->bintreenode);
   inf_double_return(v);
   sumofsquare += v * v;
   inf_double_return(sumofsquare);
   p = p->next;
  }

 return sumofsquare;
}

/*   名称: cubicsum
*    功能: 返回参数的立方和
*  返回值: 返回立方和;参数中有INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*/
double cubicsum(const List head)
{
 double v;
 double sumofcubic;
 register List p = head;

 v = caltree(p->bintreenode);
 inf_double_return(v);
 sumofcubic = v * v * v;
 inf_double_return(sumofcubic);

 p = p->next;
 while(p)
  {
   v = caltree(p->bintreenode);
   inf_double_return(v);
   sumofcubic += v * v * v;
   inf_double_return(sumofcubic);
   p = p->next;
  }

 return sumofcubic;
}

/*   名称: iif
*    功能: 根据表达式结果选择返回两个结果中的一个
*  返回值: condition为非0时返回 truepart计算结果,0时返回 falsepart计算结果;condition为INF或IND时直接返回
*    参数: const bintree *condition  做为比较条件的表达式树根节点
*          const bintree *truepart   做为返回值的表达式树根节点
*          const bintree *falsepart  做为返回值的表达式树根节点
*/
double iif(const bintree *condition, const bintree *truepart, const bintree *falsepart)
{
 double v = caltree(condition);

 inf_double_return(v);

 if (v)
  return caltree(truepart);
 else
  return caltree(falsepart);
}

/*   名称: iiif
*    功能: 根据表达式结果选择返回若干结果中的一个
*  返回值: condition为1时返回参数链表中的第二项的值,2时返回第三项的值,以此类推;condition为INF或IND时直接返回
*    参数: const List head  指向参数链表头结点的常指针
*
*    说明: 参数至少必须有两项,condition小于1时,返回第二项的值,大于参数项数时返回最后一项
*/
double iiif(const List head)
{
 const unsigned long firstvalue = 2UL;

 register List p = head;
 List p1;
 double v;
 unsigned long i, n;

 if (p == NULL || p->next == NULL)
  return 0;

 v = caltree(p->bintreenode);
 inf_double_return(v);

 if (v < firstvalue)
  return caltree(p->next->bintreenode);

 if (v <= 4294967295UL)
  n = (unsigned long)v;
 else
  n = 4294967295UL;

 i = firstvalue;
 p1 = p->next;
 p = p->next2;
 while(p)
  {
   p1 = p;
   if (i == n)
    return caltree(p->bintreenode);

   p = p->next;
   i++;
  }

 return caltree(p1->bintreenode);
}

/*   名称: nofun
*    功能: 返回参数链表中的指定项
*  返回值: index 1 返回参数链表中的第一项的值,2 返回参数链表中的第二项的值,以此类推
*    参数: const List head  指向参数链表头结点的常指针
*          unsigned long index 索引
*/
double nofun(const List head, unsigned long index)
{
 register List p = head;
 register unsigned long n = 1UL;
 double v;

 while(p)
  {
   if (n == index)
    return caltree(p->bintreenode);

   if (n == 4294967295UL)
    break;

   p = p->next;
   n++;
  }

 filldoublewithind(v);

 return v;
}

/*   名称: getfunptr
*    功能: 获取函数指针
*  返回值: 返回函数参数个数
*    参数: const char *szfunname 指向函数名称字符串的常指针
*          vfunptr *funp  指向函数指针变量的指针
*/
int getfunptr(const char *szfunname, vfunptr *funp)
{
 if (szfunname == NULL || funp == NULL)
  return 0;

 if (strcmp(szfunname, "sin") == 0)
  {
   *funp = (vfunptr)&sin;
   return 1;
  }
 if (strcmp(szfunname, "cos") == 0)
  {
   *funp = (vfunptr)&cos;
   return 1;
  }
 if (strcmp(szfunname, "tan") == 0)
  {
   *funp = (vfunptr)&tan;
   return 1;
  }
 if (strcmp(szfunname, "cot") == 0)
  {
   *funp = (vfunptr)&cot;
   return 1;
  }
 if (strcmp(szfunname, "asin") == 0)
  {
   *funp = (vfunptr)&asin;
   return 1;
  }
 if (strcmp(szfunname, "acos") == 0)
  {
   *funp = (vfunptr)&acos;
   return 1;
  }
 if (strcmp(szfunname, "atan") == 0)
  {
   *funp = (vfunptr)&atan;
   return 1;
  }
 if (strcmp(szfunname, "sinh") == 0)
  {
   *funp = (vfunptr)&sinh;
   return 1;
  }
 if (strcmp(szfunname, "cosh") == 0)
  {
   *funp = (vfunptr)&cosh;
   return 1;
  }
 if (strcmp(szfunname, "tanh") == 0)
  {
   *funp = (vfunptr)&tanh;
   return 1;
  }
 if (strcmp(szfunname, "csc") == 0)
  {
   *funp = (vfunptr)&csc;
   return 1;
  }
 if (strcmp(szfunname, "sec") == 0)
  {
   *funp = (vfunptr)&sec;
   return 1;
  }
 if (strcmp(szfunname, "sqrt") == 0)
  {
   *funp = (vfunptr)&sqrt;
   return 1;
  }
 if (strcmp(szfunname, "log") == 0)
  {
   *funp = (vfunptr)&log;
   return 1;
  }
 if (strcmp(szfunname, "log10") == 0)
  {
   *funp = (vfunptr)&log10;
   return 1;
  }
 if (strcmp(szfunname, "fabs") == 0)
  {
   *funp = (vfunptr)&fabs;
   return 1;
  }
 if (strcmp(szfunname, "exp") == 0)
  {
   *funp = (vfunptr)&exp;
   return 1;
  }
 if (strcmp(szfunname, "sgn") == 0)
  {
   *funp = (vfunptr)&sgn;
   return 1;
  }
 if (strcmp(szfunname, "ceil") == 0)
  {
   *funp = (vfunptr)&ceil;
   return 1;
  }
 if (strcmp(szfunname, "floor") == 0)
  {
   *funp = (vfunptr)&floor;
   return 1;
  }

 if (strcmp(szfunname, "atan2") == 0)
  {
   *funp = (vfunptr)&atan2;
   return 2;
  }
 if (strcmp(szfunname, "pow") == 0)
  {
   *funp = (vfunptr)&pow;
   return 2;
  }
 if (strcmp(szfunname, "logr") == 0)
  {
   *funp = (vfunptr)&logr;
   return 2;
  }
 if (strcmp(szfunname, "fmod") == 0)
  {
   *funp = (vfunptr)&fmod;
   return 2;
  }

 if (strcmp(szfunname, "mid3") == 0)
  {
   *funp = (vfunptr)&mid3;
   return 3;
  }
 if (strcmp(szfunname, "iif") == 0)
  {
   *funp = (vfunptr)&iif;
   return 3;
  }

 if (strcmp(szfunname, "max") == 0)
  {
   *funp = (vfunptr)&max_;
   return -1;
  }
 if (strcmp(szfunname, "min") == 0)
  {
   *funp = (vfunptr)&min_;
   return -1;
  }
 if (strcmp(szfunname, "mean") == 0)
  {
   *funp = (vfunptr)&mean;
   return -1;
  }
 if (strcmp(szfunname, "sum") == 0)
  {
   *funp = (vfunptr)∑
   return -1;
  }
 if (strcmp(szfunname, "squaresum") == 0)
  {
   *funp = (vfunptr)&squaresum;
   return -1;
  }
 if (strcmp(szfunname, "cubicsum") == 0)
  {
   *funp = (vfunptr)&cubicsum;
   return -1;
  }
 if (strcmp(szfunname, "iiif") == 0)
  {
   *funp = (vfunptr)&iiif;
   return -1;
  }

 return 0;
}

/*   名称: strtodouble
*    功能: 将字符串转为double型浮点数
*  返回值: 返回转换后double值
*    参数: const char *sznum  指向数字字符串常指针
*/
double strtodouble(const char *sznum)
{
 double v;

 if (isconstant(sznum, &v))
  return v;

 /* 变量 */
 if (isvariable(sznum, &v))
  return v;

 return atof(sznum);
}

/*   名称: isconstant
*    功能: 检查字符串是否为常数
*  返回值: 是 由variable接收常量值 返回1,不是返回0
*    参数: const char *sznum  欲检查字符串
*          double *variable   用于接收常量值的指针,为NULL时不反回常量值
*/
int isconstant(const char *sznum, double *variable)
{
 if (sznum == NULL)
  return 0;

 if (sznum[1] == '\0')
  {
   if (sznum[0] == 'E')
    {
     if (variable != NULL)
      *variable = E;

     return 1;
    }
  }
 if (sznum[2] == '\0')
  {
   if ((sznum[0] == 'P' && sznum[1] == 'I') || (sznum[0] == 'p' && sznum[1] == 'i'))
    {
     if (variable != NULL)
      *variable = PI;

     return 1;
    }
  }
 else if (sznum[4] == '\0')
  {
   if ((sznum[0] == 'P' && sznum[1] == 'I' && sznum[2] == '_' && sznum[3] == '2') || (sznum[0] == 'p' && sznum[1] == 'i' && sznum[2] == '_' && sznum[3] == '2'))
    {
     if (variable != NULL)
      *variable = PI_2;

     return 1;
    }
  }
 else if (strcmp(sznum, "SQRT2") == 0)
  {
   if (variable != NULL)
    *variable = SQRT2;

   return 1;
  }

 return 0;
}

/*   名称: isvariable
*    功能: 检查字符串是否为已定义的变量
*  返回值: 是 由variable接收变量值 返回1,不是返回0
*    参数: const char *sznum  欲检查字符串
*          double *variable   用于接收变量值的指针,为NULL时不返回变量值
*/
int isvariable(const char *sznum, double *variable)
{
 if (sznum == NULL)
  return 0;

 return 0;
}

/*   名称: checknum
*    功能: 检查字符串是否为合法浮点数
*  返回值: 合法返回1,不合法返回0
*    参数: const char *sznum  要检查的字符串
*/
int checknum(register const char *sznum)
{
 int point = 0;
 int exponent = 0;
 int space = 0;
 long num1 = 0L, num2 = 0L;

 if (sznum == NULL)
  return 0;

 while(*sznum)
  {
   if (isdigit(*sznum))
    {
     if (space)
      return 0;

     if (exponent)
      num2++;
     else
      num1++;
    }
   else if (*sznum == '+' || *sznum == '-')
    {
     if (space)
      return 0;

     if (exponent)  /* 指数部分 */
      {
       if (*(sznum - 1) != 'e' && *(sznum - 1) != 'E')
        return 0;
      }
     else  /* 开头部分 */
      {
       if (num1 > 0L || point)
        return 0;
      }
    }
   else if (*sznum == '.')
    {
     if (point || exponent || space)
      return 0;

     point = 1;
    }
   else if (*sznum == 'e' || *sznum == 'E')
    {
     if (exponent || num1 == 0L || space)
      return 0;

     exponent = 1;
    }
   else if (*sznum == ' ')
    {
     if (num1 || point)
      space = 1;
    }
   else
    {
     return 0;
    }

   sznum++;
  }

 if (num1 == 0L || (exponent && num2 == 0L))
  return 0;

 return 1;
}

/*   名称: islegaldoublenum
*    功能: 检查字符串内容表示的双精度值是否合法
*  返回值: 合法返回1,不合法返回0
*    参数: const char *sznum  要检查的字符串
*/
int islegaldoublenum(const char *sznum)
{
 double v;

 if (checknum(sznum))
  {
   v = atof(sznum);
   checkdoublereturn(v);
  }
 else
  return 0;
}

/*   名称: bracketsmatchingcheck
*    功能: 检查字符串括号是否匹配
*  返回值: 括号匹配正确 返回1值,否则返回0值。 
*    参数: const char *szsrc  为待检测字符串。
*/
int bracketsmatchingcheck(const char *szsrc)
{  
 const char *ptr = szsrc, *ptr1;  
 char c;  
 long brackets[3] = {0, 0, 0}; /* 括号计数器 0--(), 1--[], 2--{} */  
  
 if (szsrc == NULL)  
  return 1;
  
 while(*ptr) /* 第一次扫描 */  
  {  
   c = *ptr;    
   if (c == '(')  
    brackets[0]++;     
   else if (c == ')')  
    {  
     if (--brackets[0] == -1)  
      return 0;  
    }     
   else if (c == '[')  
    brackets[1]++;     
   else if (c == ']')  
    {  
     if (--brackets[1] == -1)  
      return 0;  
    }     
   else if (c == '{')  
    brackets[2]++;     
   else if (c == '}')  
    {  
     if (--brackets[2] == -1)  
      return 0;  
    }     
  
   ptr++;  
  }  
  
 if (brackets[0] != 0 || brackets[1] != 0 || brackets[2] != 0) /* 括号不匹配,退出 */  
  return 0;  
  
 ptr = szsrc;  
 while(*ptr) /* 第二次扫描 */  
  {  
   if (*ptr == ']')  
    {  
     brackets[0] = 0;  
     brackets[1] = 1;  
     brackets[2] = 0;  
     ptr1 = ptr - 1;  
     while(1)   
      {  
       c = *ptr1;  
       if (c == '[')   
        {  
         brackets[1]--;  
         if (brackets[1] == 0)   
          {  
           if ( brackets[0] != 0 || brackets[2] != 0)  
            return 0;  
           else  
            break;  
          }  
        }  
       else if (c == ']')   
        brackets[1]++;  
       else if (c == ')')   
        brackets[0]++;  
       else if (c == '(')   
        {  
         if (--brackets[0] == -1)  
          return 0;  
        }  
       else if (c == '}')   
        brackets[2]++;  
       else if (c == '{')   
        brackets[2]--;  
       ptr1--;  
      }  
    }  
   else if (*ptr == '}')  
    {  
     brackets[0] = 0;  
     brackets[1] = 0;  
     brackets[2] = 1;  
     ptr1 = ptr - 1;  
     while(1)   
      {  
       c = *ptr1;  
       if (c == '{')  
        {  
         brackets[2]--;  
         if (brackets[2] == 0)  
          {  
           if (brackets[0] != 0 || brackets[1] != 0)  
            return 0;  
           else  
            break;  
          }  
        }  
       else if (c == '}')  
        brackets[2]++;  
       else if (c == ')')   
        brackets[0]++;  
       else if (c == '(')   
        {  
         if (--brackets[0] == -1)  
          return 0;  
        }  
       else if (c == ']')  
        brackets[1]++;  
       else if (c == '[')  
        brackets[1]--;  
       ptr1--;  
      }  
    }  
    
   ptr++;  
  }  
  
 return 1;  
}  

/*   名称: getmaxbracketsdepth
*    功能: 获取字符串中括号嵌套最大深度
*  返回值: 返回最大深度值
*    参数: const char *szsrc  为待检测字符串。
*/
long getmaxbracketsdepth(const char *szsrc)
{
 long bracketsdepth = 0;
 long maxdepth = 0;

 if (szsrc == NULL)
  return 0;

 while(*szsrc)
  {
   if (*szsrc == '(' || *szsrc == '[' || *szsrc == '{')
    {
     if (++bracketsdepth > maxdepth)
      maxdepth = bracketsdepth;
    }
   else if (*szsrc == ')' || *szsrc == ']' || *szsrc == '}')
    {
     bracketsdepth--;
    }
   szsrc++;
  }

 return maxdepth;
}

/*   名称: caltree
*    功能: 后序遍历表达式数树计算结果 
*  返回值: 返回计算结果
*    参数: const bintree *node  欲计算的表达式树根节点
*/
double caltree(const bintree *node)
{
 double v1;
 double v2;

 if (node == NULL)
  {
   filldoublewithind(v1);

   return v1;
  }

 if (node->op == 0)
  return node->fvalue;

 if (node->op == '+')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 + v2;
  }

 if (node->op == '-')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 - v2;
  }

 if (node->op == '*')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 * v2;
  }

 if (node->op == '/')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 / v2;
  }

 if (node->op == '<')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 < v2;
  }

 if (node->op == '>')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   return v1 > v2;
  }

 if (node->op == '^')
  {
   v1 = caltree(node->lchild);
   inf_double_return(v1);

   v2 = caltree(node->rchild);
   inf_double_return(v2);

   if (node->mark & SIGNMARK)
    v1 = pow(v1, -v2);
   else
    v1 = pow(v1, v2);

   return v1;
  }

 if (node->mark & FUNCTIONMARK)
  {
   if (strcmp(((funnode *)(node->rchild))->szfunname, "iif") == 0)
    {
     /* return iif(((funnode *)(node->rchild))->para->bintreenode, ((funnode *)(node->rchild))->para->next->bintreenode, ((funnode *)(node->rchild))->para->next2->bintreenode); */
     v1 = caltree(((funnode *)(node->rchild))->para->bintreenode);
     inf_double_return(v1);

     if (v1)
      return caltree(((funnode *)(node->rchild))->para->next->bintreenode);
     else
      return caltree(((funnode *)(node->rchild))->para->next2->bintreenode);
    }
   else if (node->op == 1)
    /* return calfun1((funnode *)(node->rchild)); */
    return ((dfunptr1)((funnode *)(node->rchild))->funptr)(caltree(((funnode *)(node->rchild))->para->bintreenode));
   else if (node->op == 2)
    /* return calfun2((funnode *)(node->rchild)); */
    return ((dfunptr2)((funnode *)(node->rchild))->funptr)(caltree(((funnode *)(node->rchild))->para->bintreenode), caltree(((funnode *)(node->rchild))->para->next->bintreenode));
   else if (node->op == 3)
    /* return calfun3((funnode *)(node->rchild)); */
    return ((dfunptr3)((funnode *)(node->rchild))->funptr)(caltree(((funnode *)(node->rchild))->para->bintreenode), caltree(((funnode *)(node->rchild))->para->next->bintreenode), caltree(((funnode *)(node->rchild))->para->next2->bintreenode));
   else if (node->op == -1)
    return ((lfunptr)((funnode *)(node->rchild))->funptr)(((funnode *)(node->rchild))->para);
  }
}

/*   名称: calfun1
*    功能: 计算单参数函数
*  返回值: 返回计算结果
*    参数: const funnode *node  指向包含函数指针及参数的结构的指针
*/
double calfun1(const funnode *node)
{
 if (node == NULL)
  return 0;

 return ((dfunptr1)node->funptr)(caltree(node->para->bintreenode));
}

/*   名称: calfun2
*    功能: 计算双参数函数
*  返回值: 返回计算结果
*    参数: const funnode *node  指向包含函数指针及参数的结构的指针
*/
double calfun2(const funnode *node)
{
 if (node == NULL)
  return 0;

 return ((dfunptr2)node->funptr)(caltree(node->para->bintreenode), caltree(node->para->next->bintreenode));
}

/*   名称: calfun3
*    功能: 计算三参数函数
*  返回值: 返回计算结果
*    参数: const funnode *node  指向包含函数指针及参数的结构的指针
*/
double calfun3(const funnode *node)
{
 if (node == NULL)
  return 0;

 return ((dfunptr3)node->funptr)(caltree(node->para->bintreenode), caltree(node->para->next->bintreenode), caltree(node->para->next2->bintreenode));
}

/*   名称: createtree_
*    功能: 具体实现由字符串生成表达式树
*  返回值: 成功 返回指向生成表达式树的根节点的指针,失败 返回 NULL
*    参数: const char **szexpress  指向要生成表达式树的字符串的二级常指针
*          long *para              用于处理多参数函数的参数
*
*    说明:不直接使用由函数createtree调用,是为了遍历处理括号。
*          字符串应先由checkexpress做合法性检查,否则可能出现不可测结果。
*/
bintree *createtree_(const char **szexpress, long *para)
{
 register const char **ptr = szexpress;
 char op = 0;
 char sign = 0;                     /* 符号位:无符号--0,'-'--sign = 1 - sign;,'+'--直接略过 */
 char numstr[MAXBUFFERLEN] = {"0"}; /* 保存数字,变量名,函数名的缓冲区 */
 char *ptrnum = numstr;
 bintree *root = NULL;

 while(**ptr)
  {
   if (ptrnum != numstr)  /* 先处理科学计数指数部分+- */
    {
     if (*(ptrnum - 1) == 'e' || *(ptrnum - 1) == 'E')  /* 可能是变量名 */
      {
       if (**ptr == '+' || **ptr == '-')
        {
         *ptrnum = '\0';
         if (!(isconstant(numstr, NULL) || isvariable(numstr, NULL)))
          {
           *ptrnum++ = **ptr;

           (*ptr)++;
           continue;
          }
        }
      }
    }
   if (**ptr == '(')
    {
     bintree *subexprtree;
     long paracount = 0L;

     if (root == NULL)
      {
       (*ptr)++;
       if (ptrnum != numstr)  /* 此处就是函数,numstr是函数名 */
        {
         funnode *pfunnode;
         paranode *p1;
         paranode *p2;

         *ptrnum = '\0';
         if ((root = Alloctree) == NULL)
          return NULL;

         if (sign) /* 没有指数运算符问题 */
          {
           if ((root->lchild = Alloctree) == NULL)
            {
             free(root);

             return NULL;
            }

           if ((root->rchild = Alloctree) == NULL)
            {
             free(root->lchild);
             free(root);

             return NULL;
            }

           root->op = '-';
           root->mark = 0;
           root->lchild->op = 0;
           root->lchild->mark = 0;
           root->lchild->fvalue = 0;
           root->lchild2 = NULL;
           root->lchild->rchild = NULL;
           root->rchild->lchild = NULL;
           subexprtree = root->rchild;
          }
         else
          {
           root->lchild = NULL;
           subexprtree = root;
          }

         subexprtree->mark = BRAC_FUNMARK;
         if ((pfunnode = Allocfunnode) == NULL)
          {
           free(root);

           return NULL;
          }
         paracount = (long)(subexprtree->op = getfunptr(numstr, &pfunnode->funptr));
         if ((pfunnode->szfunname = (char *)malloc(strlen(numstr) + 1)) == NULL)
          {
           free(pfunnode);
           destorytree(&root);

           return NULL;
          }
         if ((p1 = p2 = pfunnode->para = Allocparanode) == NULL)
          {
           free(pfunnode->szfunname);
           free(pfunnode);
           free(root);

           return NULL;
          }
         strcpy(pfunnode->szfunname, numstr);
         subexprtree->rchild = (bintree *)pfunnode;

         while(paracount)  /* 以尾插法将函数参数的表达式树存入参数链表 */
          {
           if (p2 == NULL)
            {
             if ((p2 = Allocparanode) == NULL)
              {
               destorytree(&root);

               return NULL;
              }
             p1->next = p2;
            }
           p2->next = NULL;
           if ((p2->bintreenode = createtree_(ptr, ¶count)) == NULL)
            {
             destorytree(&root);

             return NULL;
            }
           p1 = p2;
           p2 = NULL;
          }
        }
       else
        {
         if (sign == 0)
          {
           if ((root = createtree_(ptr, ¶count)) == NULL)
            return NULL;
          }
         else
          {
           if ((root = Alloctree) == NULL)
            return NULL;

           if ((root->lchild = Alloctree) == NULL)
            {
             free(root);

             return NULL;
            }

           if ((root->rchild = createtree_(ptr, ¶count)) == NULL)
            {
             free(root->lchild);
             free(root);

             return NULL;
            }

           root->op = '-';
           root->mark = 0;
           root->lchild->op = 0;
           root->lchild->mark = 0;
           root->lchild->fvalue = 0;
           root->lchild2 = NULL;
           root->lchild->rchild = NULL;
          }
        }
       op = 0;
       sign = 0;
       ptrnum = numstr;

       continue;
      }

     if ((subexprtree = appendnode(&root, op, 0, 0)) == NULL)
      {
       destorytree(&root);

       return NULL;
      }
     (*ptr)++;
     if (ptrnum != numstr)  /* 此处就是函数,numstr是函数名 */
      {
       funnode *pfunnode;
       paranode *p1;
       paranode *p2;

       *ptrnum = '\0';
       /* 直接使用subexprtree->rchild作为函数节点前驱 */
       if (sign)  /* 函数前的符号位 */
        {
         if (op == '^')
          {
           subexprtree->mark |= SIGNMARK;
          }
         else  /* 0 - */
          {
           subexprtree = subexprtree->rchild;
           if ((subexprtree->lchild = Alloctree) == NULL)
            {
             destorytree(&root);

             return NULL;
            }
           subexprtree->lchild->op = 0;
           subexprtree->lchild->fvalue = 0;
           subexprtree->lchild->mark = 0;
           subexprtree->lchild2 = NULL;
           subexprtree->lchild->rchild = NULL;
           if ((subexprtree->rchild = Alloctree) == NULL)
            {
             destorytree(&root);

             return NULL;
            }
           subexprtree->rchild->lchild = NULL;
           subexprtree->rchild2 = NULL;
           subexprtree->op = '-';
          }
        }

       subexprtree->rchild->mark = BRAC_FUNMARK;
       if ((pfunnode = Allocfunnode) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
       paracount = (long)(subexprtree->rchild->op = getfunptr(numstr, &pfunnode->funptr));
       if ((pfunnode->szfunname = (char *)malloc(strlen(numstr) + 1)) == NULL)
        {
         free(pfunnode);
         destorytree(&root);

         return NULL;
        }
       if ((p1 = p2 = pfunnode->para = Allocparanode) == NULL)
        {
         free(pfunnode->szfunname);
         free(pfunnode);
         destorytree(&root);

         return NULL;
        }
       strcpy(pfunnode->szfunname, numstr);
       subexprtree->rchild2 = (bintree *)pfunnode;

       while(paracount)  /* 以尾插法将函数参数的表达式树存入参数链表 */
        {
         if (p2 == NULL)
          {
           if ((p2 = Allocparanode) == NULL)
            {
             destorytree(&root);

             return NULL;
            }
           p1->next = p2;
          }
         p2->next = NULL;
         if ((p2->bintreenode = createtree_(ptr, ¶count)) == NULL)
          {
           destorytree(&root);

           return NULL;
          }
         p1 = p2;
         p2 = NULL;
        }

       op = 0;
       sign = 0;
       ptrnum = numstr;

       continue;
      }

     free(subexprtree->rchild);  /* 删除生成新节点的右子树 */
     if (sign == 0)  /* (前的符号位 */
      {
       if ((subexprtree->rchild = createtree_(ptr, ¶count)) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
      }
     else if (op == '^')  /* ^由符号位记录负号 */
      {
       if ((subexprtree->rchild = createtree_(ptr, ¶count)) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
       subexprtree->mark |= SIGNMARK;
      }
     else
      {
       if ((subexprtree->rchild = Alloctree) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
       subexprtree->rchild->op = '-';
       subexprtree->rchild->mark = 0;
       subexprtree->rchild2 = NULL;
       if ((subexprtree->rchild->lchild = Alloctree) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
       subexprtree->rchild->lchild->op = 0;
       subexprtree->rchild->lchild->fvalue = 0;
       subexprtree->rchild->lchild->mark = 0;
       subexprtree->rchild->lchild2 = NULL;
       subexprtree->rchild->lchild->rchild = NULL;
       if ((subexprtree->rchild2 = createtree_(ptr, ¶count)) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
      }

     op = 0;
     sign = 0;
     ptrnum = numstr;
    }
   else if (**ptr == ')' || **ptr == ',')
    {
     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (root == NULL)  /* 只有一个数字,常量或变量 */
        {
         if ((root = Alloctree) == NULL)
          return NULL;

         root->op = 0;
         root->mark = 0;
         root->fvalue = (sign) ? -strtodouble(numstr) : strtodouble(numstr);
         root->lchild = NULL;
         root->rchild = NULL;

         if (**ptr == ',')
          {
           /* if (*para > 1)检查用 */
           (*para)--;
          }
         else
          {
           if (*para)
            *para = 0;
          }

         (*ptr)++;

         return root;
        }

       if (appendnode(&root, op, (sign) ? -strtodouble(numstr) : strtodouble(numstr), 0) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
      }

  #ifdef DIRECTCASIMPLE
     /* 直接计算括号内只有一步计算的表达式 */
     if (root->lchild->op == 0 && root->rchild->op == 0)
      {
       root->fvalue = caltree(root);
       root->op = 0;
       free(root->lchild);
       root->lchild = NULL;
       free(root->rchild);
       root->rchild = NULL;

       if (**ptr == ',')
        {
         /* if (*para > 1)检查用 */
         (*para)--;
        }
       else
        {
         if (*para)
          *para = 0;
        }

       (*ptr)++;

       return root;
      }
  #endif

     if (**ptr == ')')
      {
       root->mark |= BRACKETSMARK;
       if (*para)
        *para = 0;
      }
     else
      {
       /* if (*para > 1)检查用 */
       (*para)--;
      }

     (*ptr)++;

     return root;
    }
   else if (**ptr == '?')
    {
     bintree *subexprtree;
     funnode *pfunnode;

     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (root == NULL)  /* 只有一个数字,常量或变量 */
        {
         if ((root = Alloctree) == NULL)
          return NULL;

         root->op = 0;
         root->mark = 0;
         root->fvalue = (sign) ? -strtodouble(numstr) : strtodouble(numstr);
         root->lchild = NULL;
         root->rchild = NULL;
        }
       else if (appendnode(&root, op, (sign) ? -strtodouble(numstr) : strtodouble(numstr), 0) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
      }
     (*ptr)++;

     if ((subexprtree = Alloctree) == NULL)
      {
       destorytree(&root);

       return NULL;
      }

     if ((pfunnode = Allocfunnode) == NULL)
      {
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }

     subexprtree->op = getfunptr("iif", &pfunnode->funptr);
     if ((pfunnode->szfunname = (char *)malloc(strlen("iif") + 1)) == NULL)
      {
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }
     if ((pfunnode->para = Allocparanode) == NULL)
      {
       free(pfunnode->szfunname);
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }
     if ((pfunnode->para->next = Allocparanode) == NULL)
      {
       free(pfunnode->szfunname);
       free(pfunnode->para);
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }
     if ((pfunnode->para->next2 = Allocparanode) == NULL)
      {
       free(pfunnode->szfunname);
       free(pfunnode->para->next);
       free(pfunnode->para);
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }
     if ((pfunnode->para->next->bintreenode = createtree_(ptr, para)) == NULL)
      {
       free(pfunnode->szfunname);
       free(pfunnode->para->next2);
       free(pfunnode->para->next);
       free(pfunnode->para);
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }
     if ((pfunnode->para->next2->bintreenode = createtree_(ptr, para)) == NULL)
      {
       free(pfunnode->szfunname);
       free(pfunnode->para->next2);
       destorytree(&pfunnode->para->next->bintreenode);
       free(pfunnode->para->next);
       free(pfunnode->para);
       free(pfunnode);
       free(subexprtree);
       destorytree(&root);

       return NULL;
      }

     subexprtree->lchild = NULL;
     subexprtree->mark = BRAC_FUNMARK;
     subexprtree->rchild = (bintree *)pfunnode;
     strcpy(pfunnode->szfunname, "iif");
     pfunnode->para->bintreenode = root;
     pfunnode->para->next3 = NULL;
     root = subexprtree;

     return root;
    }
   else if (**ptr == ':')
    {
     (*ptr)++;
     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (root == NULL)  /* 只有一个数字,常量或变量 */
        {
         if ((root = Alloctree) == NULL)
          return NULL;

         root->op = 0;
         root->mark = 0;
         root->fvalue = (sign) ? -strtodouble(numstr) : strtodouble(numstr);
         root->lchild = NULL;
         root->rchild = NULL;

         return root;
        }

       if (appendnode(&root, op, (sign) ? -strtodouble(numstr) : strtodouble(numstr), 0) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
      }

     return root;
    }
   else if (getoperatorlevel(**ptr))
    {
     if (ptrnum != numstr)
      {
       *ptrnum = '\0';

       if (root == NULL)  /* 开头的处理 */
        {
         if ((root = Alloctree) == NULL)
          return NULL;

         if (sign == 0)
          {
           root->op = 0;
           root->mark = 0;
           root->fvalue = strtodouble(numstr);
           root->lchild = NULL;
           root->rchild = NULL;
          }
         else
          {
           if ((root->lchild = Alloctree) == NULL)
            {
             free(root);

             return NULL;
            }
           if ((root->rchild = Alloctree) == NULL)
            {
             free(root->lchild);
             free(root);

             return NULL;
            }
           root->op = '-';
           root->mark = 0;
           root->lchild->op = 0;
           root->lchild->mark = 0;
           root->lchild->fvalue = 0;
           root->lchild2 = NULL;
           root->lchild->rchild = NULL;
           root->rchild->op = 0;
           root->rchild->mark = 0;
           root->rchild->fvalue = strtodouble(numstr);
           root->rchild->lchild = NULL;
           root->rchild2 = NULL;
          }
        }
       else if (appendnode(&root, op, strtodouble(numstr), sign) == NULL)
        {
         destorytree(&root);

         return NULL;
        }
       sign = 0;
       ptrnum = numstr;
       op = **ptr;
       (*ptr)++;
      }
     else /* 连续出现运算符 */
      {
       if (root == NULL) /* 字符串最开头+-的处理 */
        {
         if (**ptr == '-')
          sign = 1 - sign;
        }
       else if (op == 0)
        {
         op = **ptr;
        }
       else if (**ptr == '-')
        {
         sign = 1 - sign;
        }

       (*ptr)++;
      }
    }
   else
    {
     if (**ptr != ' ')
      *ptrnum++ = **ptr;

     (*ptr)++;
    }
  }
 if (ptrnum != numstr)
  {
   *ptrnum = '\0';
   if (root == NULL)  /* 只有一个数字,常量或变量 */
    {
     if ((root = Alloctree) == NULL)
      return NULL;

     root->op = 0;
     root->mark = 0;
     root->fvalue = (sign) ? -strtodouble(numstr) : strtodouble(numstr);
     root->lchild = NULL;
     root->rchild = NULL;

     return root;
    }

   if (appendnode(&root, op, (sign) ? -strtodouble(numstr) : strtodouble(numstr), 0) == NULL)
    {
     destorytree(&root);

     return NULL;
    }
  }

 return root;
}

/*   名称: createtree
*    功能: 由字符串生成表达式树
*  返回值: 成功 返回指向生成表达式树的根节点的指针,失败 返回 NULL
*    参数: const char *szexpress  指向要生成表达式树的字符串的常指针
*
*    说明:具体由函数createtree_实现。
*          字符串应先由checkexpress做合法性检查,否则可能出现不可测结果。
*/
bintree *createtree(const char *szexpress)
{
 const char *ptr = szexpress;
 long para = 0;

 if (szexpress == NULL)
  return NULL;

 return createtree_(&ptr, ¶);
}

/*   名称: checkexpression
*    功能: 检查字符串是否为合法表达式
*  返回值: 合法 返回1,不合法返回 0
*    参数: const char *szexpress  指向要检查字符串的常指针
*
*    说明:具体由函数checkexpression_实现。
*/
int checkexpression(const char *szexpress)
{
 const char *ptr = szexpress;
 long para = 0;

 if (szexpress == NULL)
  return 0;

 return checkexpression_(&ptr, 0, ¶);
}

/*   名称: checkexpression_
*    功能: 检查字符串是否为合法表达式
*  返回值: 合法 返回1,不合法返回 0
*    参数: const char **szexpress  指向要检查字符串的二级常指针
*          int colon  用于处理问号运算符,第二段为1,非第二段为0?
*          long *para 用于处理函数参数
*
*    说明:不直接使用由函数checkexpression调用,是为了遍历处理括号。
*/
int checkexpression_(const char **szexpress, int colon, long *para)
{
 register const char **ptr = szexpress;
 char op = 0;
 char nospace = 0;                   /* 用于输入错误空格检查 */
 char numstr[MAXBUFFERLEN] = {"0"};  /* 保存数字,变量名,函数名的缓冲区 */
 char *ptrnum = numstr;
 int crteatetree = 0;

 while(**ptr)
  {
   if (nospace && ptrnum != numstr)  /* 先处理科学计数指数部分+- */
    {
     if (*(ptrnum - 1) == 'e' || *(ptrnum - 1) == 'E')  /* 可能是变量名 */
      {
       if (**ptr == '+' || **ptr == '-')
        {
         *ptrnum = '\0';
         if (!(isconstant(numstr, NULL) || isvariable(numstr, NULL)))
          {
           *ptrnum++ = **ptr;

           (*ptr)++;
           continue;
          }
        }
      }
    }
   if (**ptr == '(')
    {
     long paracount = 0;

     if (crteatetree && op == 0)
      return 0;

     (*ptr)++;
     if (ptrnum != numstr)  /* 此处是函数,numstr是函数名 */
      {
       vfunptr funp;
       long n;  /* 用于记录处理过的函数参数个数比如iiif的 */

       *ptrnum = '\0';
       if ((paracount = getfunptr(numstr, &funp)) == 0)  /* 检查函数名 */
        return 0;

       n = 0;
       while(paracount)  /* 检查函数参数 */
        {
         if ((crteatetree = checkexpression_(ptr, 0, ¶count)) == 0)
          return 0;

         n++;
        }
       if (strcmp(numstr, "iiif") == 0)  /* iiif至少必须有两个参数 */
        {
         if (n < 2)
          return 0;
        }
      }
     else
      {
       if ((crteatetree = checkexpression_(ptr, 0, ¶count)) == 0)
        return 0;
      }

     op = 0;
     ptrnum = numstr;
     nospace = 0;
    }
   else if (**ptr == ')' || **ptr == ',')  /* ,用于分割函数参数 */
    {
     if (crteatetree == 0 && ptrnum == numstr)  /* 空括号报错 */
      return 0;

     if (colon)
      return 0;

     if (**ptr == ',')
      {
       if (*para > 1)
        (*para)--;
       else if (*para != -1)
        return 0;
      }
     else
      {
       if (*para > 1)
        return 0;

       if (*para == 1 || *para == -1)
        *para = 0;
      }

     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (crteatetree == 0)  /* 只有一个数字 */
        {
         (*ptr)++;
         return islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL);
        }
       else if (op == 0)
        return 0;

       crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL);
      }
     else if (op)
      return 0;

     (*ptr)++;

     return crteatetree;
    }
   else if (**ptr == '?')
    {
     if (crteatetree == 0 && ptrnum == numstr)  /* 空串报错 */
      return 0;

     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (crteatetree == 0)  /* 只有一个数字 */
        {
         if ((crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL)) == 0)
          return 0;
        }
       else if (op == 0)
        return 0;

       if ((crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL)) == 0)
        return 0;
      }
     else if (op)
      return 0;

     (*ptr)++;

     if ((crteatetree = checkexpression_(ptr, 1, para)) == 0)
      return 0;

     crteatetree = 0;
     op = 0;
     ptrnum = numstr;
     nospace = 0;
    }
   else if (**ptr == ':')
    {
     if (!colon)
      return 0;

     if (crteatetree == 0 && ptrnum == numstr)  /* 空串报错 */
      return 0;

     if (ptrnum != numstr)
      {
       *ptrnum = '\0';
       if (crteatetree == 0)  /* 只有一个数字 */
        {
         if ((crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL)) == 0)
          return 0;
        }
       else if (op == 0)
        return 0;

       if ((crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL)) == 0)
        return 0;
      }
     else if (op)
      return 0;

     (*ptr)++;

     return crteatetree;
    }
   else if (getoperatorlevel(**ptr))
    {
     nospace = 0;
     if (ptrnum != numstr)
      {
       if (crteatetree && op == 0)
        return 0;

       *ptrnum = '\0';
       if ((crteatetree = (islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL))) == 0)
        return 0;

       ptrnum = numstr;
       op = **ptr;
       (*ptr)++;
      }
     else  /* 连续出现运算符 */
      {
       if (crteatetree == 0)    /* 字符串最开头+-的处理 */
        {
         if (**ptr == '-')
          ;                     /* sign = 1 - sign */
         else if (**ptr != '+') /* +-以外的运算符报错 */
          return 0;             /* printf("err\n"); */
        }
       else if (op == 0)
        op = **ptr;
       else if (**ptr == '-')
        ;                       /* sign = 1 - sign */
       else if (**ptr != '+')   /* +-以外的运算符报错 */
        return 0;               /* printf("err\n"); */

       (*ptr)++;
      }
    }
   else
    {
     if (**ptr == ' ')
      nospace = 0;
     else
      {
       if (ptrnum != numstr)
        {
         if (nospace == 0)  /* 错误空格 */
          return 0;         /* printf("err\n"); */
        }
       *ptrnum++ = **ptr;
       nospace = 1;
      }

     (*ptr)++;
    }
  }
 if (colon)
  return 0;

 if (ptrnum != numstr)
  {
   if (crteatetree && op == 0)
    return 0;

   *ptrnum = '\0';
   crteatetree = islegaldoublenum(numstr) || isconstant(numstr, NULL) || isvariable(numstr, NULL);
  }
 else if (op)
  return 0;

 return crteatetree;
}


 

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:19230次
    • 积分:500
    • 等级:
    • 排名:千里之外
    • 原创:29篇
    • 转载:3篇
    • 译文:0篇
    • 评论:1条
    文章分类