1、表达式类型的实现c程序功能全可运行expression.cpp#includeexpression.h#includemath.h#include #define pi 3.1415926 /*全局变量*/ int save_number51;/*在按原表达式输入形式中,输入的常量保存到数组save_number中,常量最多为50个,0单元不用*/ char Expr_String50;/*存放表达式的字符串*/ /*以字符序列的形式输入语法正确的前缀表达式,保存到字符串string*/ /*参数flag=0表示输出的提示信息是请输入正确的前缀表示式:*/ /*flag=1表示输出的提示信息为
2、请以表达式的原书写形式输入正确表示式:*/ Status Input_Expr(char *string,int flag) if(flag=0)printf(n请输入正确的前缀表示式:); else printf(n请以表达式的原书写形式输入正确表示式:); flushall();/*清理缓冲区*/ gets(string);/*从键盘输入一串字符串作为表达式*/ if(strlen(string)=1)/*输入的表达式字符串长度为1*/ if(string0=+|string0=-|string0=*|string0=/|string0=)/*输入的表达式只有一个运算符*/ printf(
3、n表达式只有一个字符,为运算符,错误!);return ERROR; else if(string0=0&string0=a&string0=A&string0=0&stringidata.tag=INT;(*E)-data.num=stringi-48; else if(stringi=1&stringidata.tag=INT;(*E)-data.num=save_numberstringi; else/*为变量*/ (*E)-data.tag=CHAR;(*E)-data.c=stringi; /*以正确的前缀表示式并构造表达式E*/ Status ReadExpr(BiTree *E,
4、char *exprstring) SqStack S;/定义顺序栈S int i,len;/*len为表达式的长度*/ BiTree p,q; (*E)=(BiTree)malloc(sizeof(BiTNode);/*申请二叉树的根结点的空间*/ (*E)-lchild=NULL; (*E)-rchild=NULL; len=strlen(exprstring);/*len赋值为表达式的长度*/ if(len=1)/*表达式长度为1时,二叉树只有根结点*/ judge_value(E,exprstring,0);/*将exprstring0存入二叉树的结点中*/ else judge_va
5、lue(E,exprstring,0);/*将exprstring0存入二叉树的结点中*/ InitStack(&S);/*初始化栈*/ q=(*E); Push(&S,q);/*入栈*/ Push(&S,q);/*入栈,根结点入栈两次是为判断先序输入的表达式是不是正确的表达式*/ for(i=1;ilchild=NULL; p-rchild=NULL; if(exprstringi=+|exprstringi=-|exprstringi=*|exprstringi=/|exprstringi=) /*为运算符,运算符入栈,左孩子不空,向左孩子走,否则,如果右孩子不空,向右孩子走*/ if(!
6、q-lchild) q-lchild=p;Push(&S,p);q=p; else q-rchild=p;Push(&S,p);q=p; else/*不是运算符,运算符出栈*/ if(!q-lchild) q-lchild=p;Pop(&S,&q); else q-rchild=p;Pop(&S,&q); if(StackEmpty(S)&i=len) return OK;/*栈空且i=len,说明输入的表达式是正确的*/ else /*输入的表达式是错误的*/ printf(n输入的表达式有误!); return ERROR; /*如果两个字符是运算符,比较两个运算符的优先级,c1比c2优先
7、,返回OK,否则返回ERROR*/ Status Pri_Compare(char c1,char c2) if(c1=|c1=*|c1=-|c1=+|c1=/)&(c2=|c2=*|c2=-|c2=+|c2=/) /*c1和c2为运算符*/ if(c1=)/*c1为指数运算符,则当c2不为时,c1比c2优先*/ if(c2!=) return OK; else return ERROR; else if(c1=*|c1=/)/*c1为乘法或除法运算符,则当c2为+或-,c1比c2优先*/ if(c2=|c2=*|c2=/) return ERROR; else return OK; else
8、 return ERROR;/*其余,c1不比c2优先*/ else return ERROR;/*c1和c2不是运算符*/ /*用带括弧的中缀表达式输出表达式*/ void WriteExpr(BiTree E) if(E)/*树不为空*/ /*先递归左子树*/ if(E-lchild&E-lchild-data.tag=CHAR)/*E的左孩子不为空,且左孩子为字符*/ if(Pri_Compare(E-data.c,E-lchild-data.c)/*E-data.c比E-lchild-data.c优先*/ printf(); WriteExpr(E-lchild); printf();
9、/*带括弧输出左子树*/ else WriteExpr(E-lchild);/*否则,不带括弧输出左子树*/ else WriteExpr(E-lchild);/*否则,输出左子树*/ /*访问输出根结点的值*/ if(E-data.tag=INT)printf(%d,E-data.num); else printf(%c,E-data.c); /*后递归右子树*/ if(E-rchild&E-rchild-data.tag=CHAR)/*E的右孩子不为空,且右孩子为字符*/ if(Pri_Compare(E-data.c,E-rchild-data.c)/*E-data.c比E-rchild
10、-data.c优先*/ printf();WriteExpr(E-rchild);printf();/*带括弧输出右子树*/ else WriteExpr(E-rchild);/*否则,不带括弧输出右子树*/ else WriteExpr(E-rchild);/*否则,输出右子树*/ /*实现对表达式中的所有变量V的赋值(V=c),参数flag为表示是否赋值过的标志*/ void Assign(BiTree *E,char V,int c,int *flag) if(*E) if(*E)-data.tag=CHAR&(*E)-data.c=V)/*如果找到要赋值的变量,赋值*/ (*E)-da
11、ta.tag=INT;(*E)-data.num=c;*flag=1; Assign(&(*E)-lchild),V,c,flag);/*递归左子树*/ Assign(&(*E)-rchild),V,c,flag);/*递归左子树*/ /*指数运算函数,底数为x,指数为exp*/ long power(int x,int exp) long result; int i; for(i=1,result=1;idata.tag=CHAR)/*树不为空*/ if(E-data.c!=*&E-data.c!=&E-data.c!=-&E-data.c!=+&E-data.c!=/) printf(n表
12、达式中仍存在变量没有赋值!没法求出表达式的值!);return ERROR; /*存在变量,提示信息,后返回ERROR*/ if(Check(E-lchild)/*递归左子树*/ Check(E-rchild);/*递归右子树*/ /*对算术表达式求值*/ long Value(BiTree E) if(E)/*树不为空*/ if(!E-lchild&!E-rchild&E-data.tag=INT) return (E-data.num); /*结点的左孩子和右孩子为空,为叶子结点,返回结点的值*/ return Operate(Value(E-lchild),E-data.c,Value(
13、E-rchild); /*运算求值,后根遍历的次序对表达式求值,其中参数递归调用了Value()函数求左子树的值和右子树的值*/ /*构造一个新的复合表达式*/ void CompoundExpr(char P,BiTree *E1,BiTree E2) BiTree E; E=(BiTree)malloc(sizeof(BiTNode);/*申请一个结点存放运算符P*/ E-data.tag=CHAR; E-data.c=P;/*申请到的结点值为P*/ E-lchild=(*E1);/*结点的左孩子为E1*/ E-rchild=E2;/*结点的右孩子为E2*/ (*E1)=E;/*(*E1)
14、为根结点*/ printf(n表达式E复合成功!其表达式变为:n); WriteExpr(E);/*输出复合好的表达式*/ /*以表达式的原书写形式输入,表达式的原书写形式字符串string变为字符串pre_expr*/ /*后调用reversal_string()函数反转得到前缀表达式pre_expr*/ Status Read_Inorder_Expr(char *string,char *pre_expr) int i,j,len,char_number=1;/*len表示字符串string的长度,char_number是记录数组save_number的个数*/ int number;/
15、*保存大于9的常量*/ char c,c1; SqStack1 S;/*栈定义*/ InitStack1(&S);/*初始栈*/ Push1(&S,#);/*先将字符#入栈,用来表示作为栈的最底一个元素*/ len=strlen(string);/*len为字符串string的长度*/ c=stringlen-1;/*从字符串的最后一个字符开始向前扫描*/ i=len-1; while(!StackEmpty1(S)&i=0)/*栈不为空且i大于等于0*/ if(c=()/*字符为(*/ Pop1(&S,&c);/*出栈,赋值给c*/ while(c!=)/*假如c不为),出栈*/ *pre_
16、expr+=c; if(!StackEmpty1(S)&GetTop1(S,&c1)&c1!=#) Pop1(&S,&c); else printf(n输入的表达式有误!);return ERROR; else if(c=)/*字符为),入栈*/ Push1(&S,c); else if(c=0&c=0&c1=0;j+,i-)/*循环扫描string前一个字符,求出常量后赋给number*/ number=(c1-48)*power(10,j)+number;/*number为扫描到的常量*/ c1=stringi-2; save_numberchar_number=number;/*将num
17、ber存入到数组save_number中,下标为char_number*/ *pre_expr+=char_number+; else if(c=a&c=A&c=0&stringi-1=A&stringi-1=a&stringi-1=0) c=stringi;/*i不小于0,c=stringi循环下一个字符*/ else /*否则,将清空栈*/ while(!StackEmpty1(S)&GetTop1(S,&c1)&c1!=#) Pop1(&S,&c);*pre_expr+=c; Pop1(&S,&c);/*将#出栈*/ *pre_expr=0;/*字符串结束符*/ if(i0&StackE
18、mpty1(S)return OK; else return ERROR; /*将字符串exprstring反转过来*/ void reversal_string(char *exprstring) int len,i,j; char temp; len=strlen(exprstring);/*len为exprstring的长度*/ for(i=0,j=len-1;ilchild&(*E)-rchild)/*左右孩子不为空*/ if(*E)-lchild-data.tag=INT&(*E)-rchild-data.tag=INT)/*假如左右孩子为常量,合并*/ result=Operate
19、(*E)-lchild-data.num,(*E)-data.c,(*E)-rchild-data.num);/*常数合并运算,调用Operate()函数求值*/ (*E)-data.tag=INT;(*E)-data.num=result;/*修改之前的运算符为常量*/ free(*E)-lchild);/*释放左孩子*/ free(*E)-rchild);/*释放右孩子*/ (*E)-lchild=(*E)-rchild=NULL;/*左右孩子置空*/ else MergeConst(&(*E)-lchild);/*递归左孩子*/ MergeConst(&(*E)-rchild);/*递归右孩子*/ /判断是否操作符 int isoperator(char c) switch(c) case +: return TR
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1