二叉树计算中缀表达式,支持科学计数法,支持前导正负号,支持指数运算符“^”,支持括号,支持函数,具有错误检查。以字符串形式输入。
#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;
}