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

642人阅读 评论(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);
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 mid3(double v1, double v2, double v3);
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 *p;

return;

while(p)
{

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

/*   名称: 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 v;
double v1;

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 v;
double v1;

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 sum;
register long n = 1L;

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 v;
double sum;

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 v;
double sumofsquare;

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 v;
double sumofcubic;

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时，返回第二项的值，大于参数项数时返回最后一项
*/
{
const unsigned long firstvalue = 2UL;

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 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网站的观点或立场
个人资料
• 访问：24213次
• 积分：490
• 等级：
• 排名：千里之外
• 原创：29篇
• 转载：3篇
• 译文：0篇
• 评论：1条
文章分类
评论排行