表达式类型的实现c程序功能全可运行.docx

上传人:b****8 文档编号:9784571 上传时间:2023-02-06 格式:DOCX 页数:31 大小:24.78KB
下载 相关 举报
表达式类型的实现c程序功能全可运行.docx_第1页
第1页 / 共31页
表达式类型的实现c程序功能全可运行.docx_第2页
第2页 / 共31页
表达式类型的实现c程序功能全可运行.docx_第3页
第3页 / 共31页
表达式类型的实现c程序功能全可运行.docx_第4页
第4页 / 共31页
表达式类型的实现c程序功能全可运行.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

表达式类型的实现c程序功能全可运行.docx

《表达式类型的实现c程序功能全可运行.docx》由会员分享,可在线阅读,更多相关《表达式类型的实现c程序功能全可运行.docx(31页珍藏版)》请在冰豆网上搜索。

表达式类型的实现c程序功能全可运行.docx

表达式类型的实现c程序功能全可运行

expression.cpp

#include"expression.h"

#include"math.h"

#include

#definepi3.1415926

/*全局变量*/

intsave_number[51];/*在按原表达式输入形式中,输入的常量保存到数组save_number中,常量最多为50个,0单元不用*/

charExpr_String[50];/*存放表达式的字符串*/

/*以字符序列的形式输入语法正确的前缀表达式,保存到字符串string*/

/*参数flag=0表示输出的提示信息是"请输入正确的前缀表示式:

"*/

/*flag=1表示输出的提示信息为"请以表达式的原书写形式输入正确表示式:

"*/

StatusInput_Expr(char*string,intflag)

{

if(flag==0)printf("\n请输入正确的前缀表示式:

");

elseprintf("\n请以表达式的原书写形式输入正确表示式:

");

flushall();/*清理缓冲区*/

gets(string);/*从键盘输入一串字符串作为表达式*/

if(strlen(string)==1)/*输入的表达式字符串长度为1*/

if(string[0]=='+'||string[0]=='-'||string[0]=='*'||string[0]=='/'||string[0]=='^')/*输入的表达式只有一个运算符*/

{printf("\n表达式只有一个字符,为运算符,错误!

");returnERROR;}

elseif((string[0]>='0'&&string[0]<'9')||(string[0]>='a'&&string[0]<='z')||(string[0]>='A'&&string[0]<='Z'))

/*输入的表达式只有一个数字或字符*/

{printf("\n表达式只有一个字符!

");returnOK;}

else{printf("\n输入的字符不是运算符也不是变量常量,错误!

");returnERROR;}

returnOK;

}

/*判断字符string[i],如果是'0'-'9'常量之间,二叉树结点存为整型;否则,存为字符型*/

voidjudge_value(BiTree*E,char*string,inti)

{

if(string[i]>='0'&&string[i]<='9')/*为常量*/

{(*E)->data.tag=INT;(*E)->data.num=string[i]-48;}

elseif(string[i]>=1&&string[i]<=20)/*为常量,常量存于数组save_number中*/

{(*E)->data.tag=INT;(*E)->data.num=save_number[string[i]];}

else/*为变量*/

{(*E)->data.tag=CHAR;(*E)->data.c=string[i];}

}

/*以正确的前缀表示式并构造表达式E*/

StatusReadExpr(BiTree*E,char*exprstring)

{

SqStackS;//定义顺序栈S

inti,len;/*len为表达式的长度*/

BiTreep,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);/*将exprstring[0]存入二叉树的结点中*/

else

{

judge_value(E,exprstring,0);/*将exprstring[0]存入二叉树的结点中*/

InitStack(&S);/*初始化栈*/

q=(*E);

Push(&S,q);/*入栈*/

Push(&S,q);/*入栈,根结点入栈两次是为判断先序输入的表达式是不是正确的表达式*/

for(i=1;i

StackEmpty(S);i++)//

{

p=(BiTree)malloc(sizeof(BiTNode));

judge_value(&p,exprstring,i);/*将exprstring[i]存入二叉树的结点中*/

p->lchild=NULL;

p->rchild=NULL;

if(exprstring[i]=='+'||exprstring[i]=='-'||exprstring[i]=='*'||exprstring[i]=='/'||exprstring[i]=='^')

{/*为运算符,运算符入栈,左孩子不空,向左孩子走,否则,如果右孩子不空,向右孩子走*/

if(!

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)returnOK;/*栈空且i>=len,说明输入的表达式是正确的*/

else/*输入的表达式是错误的*/

{

printf("\n输入的表达式有误!

");

returnERROR;

}

}

}

/*如果两个字符是运算符,比较两个运算符的优先级,c1比c2优先,返回OK,否则返回ERROR*/

StatusPri_Compare(charc1,charc2)

{

if((c1=='^'||c1=='*'||c1=='-'||c1=='+'||c1=='/')&&(c2=='^'||c2=='*'||c2=='-'||c2=='+'||c2=='/'))

{/*c1和c2为运算符*/

if(c1=='^')/*c1为指数运算符,则当c2不为'^'时,c1比c2优先*/

{

if(c2!

='^')returnOK;

elsereturnERROR;

}

elseif(c1=='*'||c1=='/')/*c1为乘法或除法运算符,则当c2为'+'或'-',c1比c2优先*/

{

if(c2=='^'||c2=='*'||c2=='/')returnERROR;

elsereturnOK;

}

elsereturnERROR;/*其余,c1不比c2优先*/

}

elsereturnERROR;/*c1和c2不是运算符*/

}

/*用带括弧的中缀表达式输出表达式*/

voidWriteExpr(BiTreeE)

{

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(")");}/*带括弧输出左子树*/

elseWriteExpr(E->lchild);/*否则,不带括弧输出左子树*/

}

elseWriteExpr(E->lchild);/*否则,输出左子树*/

/*访问输出根结点的值*/

if(E->data.tag==INT){printf("%d",E->data.num);}

elseprintf("%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->data.c优先*/

{printf("(");WriteExpr(E->rchild);printf(")");}/*带括弧输出右子树*/

elseWriteExpr(E->rchild);/*否则,不带括弧输出右子树*/

}

elseWriteExpr(E->rchild);/*否则,输出右子树*/

}

}

/*实现对表达式中的所有变量V的赋值(V=c),参数flag为表示是否赋值过的标志*/

voidAssign(BiTree*E,charV,intc,int*flag)

{

if(*E)

{

if((*E)->data.tag==CHAR&&(*E)->data.c==V)/*如果找到要赋值的变量,赋值*/

{(*E)->data.tag=INT;(*E)->data.num=c;*flag=1;}

Assign(&((*E)->lchild),V,c,flag);/*递归左子树*/

Assign(&((*E)->rchild),V,c,flag);/*递归左子树*/

}

}

/*指数运算函数,底数为x,指数为exp*/

longpower(intx,intexp)

{

longresult;

inti;

for(i=1,result=1;i<=exp;i++)

result*=x;

returnresult;

}

/*运算符运算求值,参数opr1,opr2为常量,opr为运算符,根据不同的运算符,实现不同的运算,返回运算结果*/

longOperate(intopr1,charopr,intopr2)

{

longresult;

switch(opr)

{

case'+':

/*加法*/

result=opr1+opr2;

returnresult;break;

case'-':

/*减法*/

result=opr1-opr2;

returnresult;break;

case'*':

/*乘法*/

result=opr1*opr2;

returnresult;break;

case'/':

/*除法,除法是在整型类型上的除法*/

result=opr1/opr2;

returnresult;break;

case'^':

/*指数运算*/

result=power(opr1,opr2);

returnresult;break;

default:

break;

}

}

/*运算符运算求值,参数opr为常量,opr1为运算符,根据不同的运算符,实现不同的运算,返回运算结果*/

doubleOperate1(charopr,doubleopr1)

{

doubleresult1,opr2;

opr2=opr1*2*pi/360;

switch(opr)

{

case's':

/*正玄sin*/

result1=sin(opr2);

returnresult1;break;

case'c':

/*余弦*/

result1=cos(opr2);

returnresult1;break;

case't':

/*正切*/

result1=tan(opr2);

returnresult1;break;

default:

break;

}

}

/*检查表达式是否还存在没有赋值的变量,以便求算数表达式的值*/

StatusCheck(BiTreeE)

{

if(E&&E->data.tag==CHAR)/*树不为空*/

{

if(E->data.c!

='*'&&E->data.c!

='^'&&E->data.c!

='-'&&E->data.c!

='+'&&E->data.c!

='/')

{printf("\n表达式中仍存在变量没有赋值!

没法求出表达式的值!

");returnERROR;}

/*存在变量,提示信息,后返回ERROR*/

if(Check(E->lchild))/*递归左子树*/

Check(E->rchild);/*递归右子树*/

}

}

/*对算术表达式求值*/

longValue(BiTreeE)

{

if(E)/*树不为空*/

{

if(!

E->lchild&&!

E->rchild&&E->data.tag==INT)return(E->data.num);

/*结点的左孩子和右孩子为空,为叶子结点,返回结点的值*/

returnOperate(Value(E->lchild),E->data.c,Value(E->rchild));

/*运算求值,后根遍历的次序对表达式求值,其中参数递归调用了Value()函数求左子树的值和右子树的值*/

}

}

/*构造一个新的复合表达式*/

voidCompoundExpr(charP,BiTree*E1,BiTreeE2)

{

BiTreeE;

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)为根结点*/

printf("\n表达式E复合成功!

其表达式变为:

\n");

WriteExpr(E);/*输出复合好的表达式*/

}

/*以表达式的原书写形式输入,表达式的原书写形式字符串string变为字符串pre_expr*/

/*后调用reversal_string()函数反转得到前缀表达式pre_expr*/

StatusRead_Inorder_Expr(char*string,char*pre_expr)

{

inti,j,len,char_number=1;/*len表示字符串string的长度,char_number是记录数组save_number[]的个数*/

intnumber;/*保存大于9的常量*/

charc,c1;

SqStack1S;/*栈定义*/

InitStack1(&S);/*初始栈*/

Push1(&S,'#');/*先将字符'#'入栈,用来表示作为栈的最底一个元素*/

len=strlen(string);/*len为字符串string的长度*/

c=string[len-1];/*从字符串的最后一个字符开始向前扫描*/

i=len-1;

while(!

StackEmpty1(S)&&i>=0)/*栈不为空且i大于等于0*/

{

if(c=='(')/*字符为'('*/

{

Pop1(&S,&c);/*出栈,赋值给c*/

while(c!

=')')/*假如c不为')',出栈*/

{

*pre_expr++=c;

if(!

StackEmpty1(S)&&GetTop1(S,&c1)&&c1!

='#')Pop1(&S,&c);

else{printf("\n输入的表达式有误!

");returnERROR;}

}

}

elseif(c==')')/*字符为')',入栈*/

{

Push1(&S,c);

}

elseif(c>='0'&&c<='9')/*字符为'0'-'9'之间,循环扫描string前一个字符,后确定常量的大小*/

{

number=c-48;/*number为第一个常量字符的ASCII码-48*/

for(c1=string[i-1],j=1;(c1>='0'&&c1<='9')&&i>=0;j++,i--)/*循环扫描string前一个字符,求出常量后

赋给number*/

{

number=(c1-48)*power(10,j)+number;/*number为扫描到的常量*/

c1=string[i-2];

}

save_number[char_number]=number;/*将number存入到数组save_number中,下标为

char_number*/

*pre_expr++=char_number++;

}

elseif((c>='a'&&c<='z')||(c>='A'&&c<='Z'))/*字符为'a'-'z'或'A'-'Z'之间的变量*/

{/*string下一个字符不能为常量或变量,否则,出错*/

if((string[i-1]>='0'&&string[i-1]<='9')||(string[i-1]>='A'&&string[i-1]<='Z')||(string[i-1]>='a'&&string[i-1]<='z'))

{printf("\n输入的表达式有误!

");returnERROR;}

else*pre_expr++=c;

}

elseif(c=='*'||c=='/')/*字符为运算符'*'或'/'*/

{

while(GetTop1(S,&c1)&&(c1=='^'))/*将c与栈顶的字符c1比较优先级*/

{Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c优先,出栈*/

Push1(&S,c);/*入栈字符c*/

}

elseif(c=='+'||c=='-')/*字符为运算符'+'或'-'*/

{

while(GetTop1(S,&c1)&&(c1=='^'||c1=='*'||c1=='/'))/*将c与栈顶的字符c1比较优先级*/

{Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c优先,出栈*/

Push1(&S,c);/*入栈运算符c*/

}

elseif(c=='^')/*字符为运算符'^'*/

{

Push1(&S,c);/*入栈运算符'^'*/

}

else{printf("\n输入的表达式有误!

");returnERROR;}/*其他字符,错误,返回ERROR*/

i--;/*下一个字符*/

if(i>=0)c=string[i];/*i不小于0,c=string[i]循环下一个字符*/

else/*否则,将清空栈*/

while(!

StackEmpty1(S)&&GetTop1(S,&c1)&&c1!

='#'){Pop1(&S,&c);*pre_expr++=c;}

}

Pop1(&S,&c);/*将'#'出栈*/

*pre_expr='\0';/*字符串结束符*/

if(i<0&&StackEmpty1(S))returnOK;

elsereturnERROR;

}

/*将字符串exprstring反转过来*/

voidreversal_string(char*exprstring)

{

intlen,i,j;

chartemp;

len=strlen(exprstring);/*len为exprstring的长度*/

for(i=0,j=len-1;i

{

temp=exprstring[i];

exprstring[i]=exprstring[j];

exprstring[j]=temp;

}

}

/*常数合并操作函数,合并表达式E中所有常数运算*/

voidMergeConst(BiTree*E)

{

longresult;

if((*E)->lchild&&(*E)->rchild)/*左右孩子不为空*/

{

if((*E)->lchild->data.tag==INT&&(*E)->rchild->data.tag==INT)/*假如左右孩子为常量,合并*/

{

result=Operate((*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));/*递归右孩子*/

}

}

}

//判断是否操作符

intisoperator(charc)

{

switch(c)

{

case'+':

returnTR

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1