数据结构实验报告五四则运算表达式求值.docx
- 文档编号:23091264
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:15
- 大小:31.27KB
数据结构实验报告五四则运算表达式求值.docx
《数据结构实验报告五四则运算表达式求值.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告五四则运算表达式求值.docx(15页珍藏版)》请在冰豆网上搜索。
数据结构实验报告五四则运算表达式求值
问题描述:
四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。
一、需求分析:
1、本程序是利用二叉树后序遍历来实现表达式的转换,同时可以使用实验三的结果来求解后缀表达式的值。
2、输入输出格式:
输入格式:
在字符界面上输入一个中缀表达式,回车表示结束。
请输入表达式:
输入一个中缀表达式
输出格式:
如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。
逆波兰表达式为:
输出逆波兰表达式
运算结果为:
输出运算后的结果
3、测试用例
输入:
21+23*(12-6)
输出:
2123126-*+
二、概要设计:
抽象数据类型
二叉树类BiTree
算法的基本思想
根据题目要求,利用栈计算,和二叉树存储,来计算表达式
该算法的基本思想是:
先利用栈进行计算,然后用二叉树进行存储,和实验三算法一样来计算逆波兰表达式的值
程序的流程
程序由三个模块组成:
(1)输入模块:
输入一个运算式
(2)计算模块:
利用栈进行表达式的计算,二叉树来存储。
(3)输出模块:
屏幕上显示出后缀表达式和运算结果。
三、详细设计
物理数据类型
程序含有两个类,其中栈不再赘述,另一个类为二叉树classBiTree包含私有成员structBiTreeNode,根节点BiTreeNode*T;索引index;intnumber_of_point优先级比较函数compare(chara,charb);生成树的函数voidInorderCreate(BiTreeNode*&T,charstr[30][10],intstart,intend);判断数字函数boolIsNumber(chara);求值函数doubleOperate(BiTreeNode*T);还有显示后缀表达式的函数voiddisplay(BiTreeNode*T);而公有成员函数则是对私有函数的重载,为方便使用,因为函数中普遍使用了递归的算法。
算法的时空分析
此算法利用栈和二叉树来实现,故次算法的的时间复杂度为(N)。
输入和输出的格式
输入格式:
请输入表达式:
输入一个中缀表达式//回车
输出格式:
逆波兰表达式为:
输出逆波兰表达式
运算结果为:
输出运算后的结果
四、调试分析
略。
五、测试结果
本实验的测试结果截图如下:
六、用户使用说明(可选)
1、本程序的运行环境为windows操作系统,执行文件为biaodashi.exe
2、运行程序时
提示输入表达式
本程序可以将中缀表达式转换为后缀表达式后在计算出运算式的结果。
提示:
请输入表达式:
输出
提示:
逆波兰表达式为:
运算结果:
七、实验心得(可选)
本次实验过程比较复杂,由于书上的知识掌握的还不是很牢靠,所以现在实验做起来有点儿吃力。
本实验主要是通过与同学的讨论和课后查阅资料来完成的,虽然有些地方还不是很懂,但基本上能完成此次实验的内容。
而且通过本次实验,加深了对二叉树算法的了解。
附录(实验代码):
#include
#include
#include
#include
#include
#include
#defineSTACK_INIT_SIZE100
#defineDATA_SIZE10
#defineSTACKINCREMENT10
#defineOK1
#defineTRUE1
#defineFALSE0
#defineERROR0
#defineOVERFLOW-2
usingnamespacestd;
typedeffloatSElemtype;
typedefintStatus;
typedefchar*TElemType;
typedefstructBiTNode{
TElemTypedata;
intlen;//data字符串中字符的个数
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
typedefstruct
{
SElemtype*base;
SElemtype*top;
intstacksize;
}SqStack;
StatusIsDigital(charch)
{if(ch>='0'&&ch<='9')
{return1;//是数字字母
}
return0;//不是数字字母
}
intCrtNode(stack
{
BiTNode*T;
inti=0;
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=(char*)malloc(DATA_SIZE*sizeof(char));
while(IsDigital(c[i]))
{T->data[i]=c[i];
i++;}
T->len=i;
T->lchild=T->rchild=NULL;
PTR.push(T);
returni;
}
voidCrtSubTree(stack
{BiTNode*T;
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=(char*)malloc(DATA_SIZE*sizeof(char));
T->data[0]=c;
T->len=1;
T->rchild=PTR.top();//先右子树,否则运算次序反了
PTR.pop();
T->lchild=PTR.top();
PTR.pop();
PTR.push(T);
}
charsymbol[5][5]={{'>','>','<','<','>'},//符号优先级
{'>','>','<','<','>'},
{'>','>','>','>','>'},
{'>','>','>','>','>'},
{'<','<','<','<','='}};
intsym2num(chars)//返回符号对应优先级矩阵位置
{switch(s)
{
case'+':
return0;break;
case'-':
return1;break;
case'*':
return2;break;
case'/':
return3;break;
case'#':
return4;break;
}
}
charPrecede(chara,charb)//返回符号优先级
{return(symbol[sym2num(a)][sym2num(b)]);}
voidCrtExptree(BiTree&T,charexp[])
{//根据字符串exp的内容构建表达式树T
stack
stack
charop;
inti=0;
OPTR.push('#');
op=OPTR.top();
while(!
((exp[i]=='#')&&(OPTR.top()=='#')))//与
{
if(IsDigital(exp[i]))
{//建立叶子节点并入栈PTR
i+=CrtNode(PTR,&exp[i]);
}
elseif(exp[i]=='')
i++;
else{
switch(exp[i])
{
case'(':
{
OPTR.push(exp[i]);
i++;
break;}
case')':
{
op=OPTR.top();OPTR.pop();
while(op!
='('){
CrtSubTree(PTR,op);
op=OPTR.top();OPTR.pop();
}//endwhile
i++;
break;}
default:
//exp[i]是+-*/
while(!
OPTR.empty())
{
op=OPTR.top();
if(Precede(op,exp[i])=='>')
{
CrtSubTree(PTR,op);
OPTR.pop();
}
if(exp[i]!
='#')
{
OPTR.push(exp[i]);
i++;
}
break;}
}//endswitch
}//endelse
}//endwhile
T=PTR.top();
PTR.pop();
}
voidPostOrderTraverse(BiTree&T,char*exp,int&count)
{
//后序遍历表达式树T,获取树中每个结点的数据值生成逆波兰表达式exp;T是表达式树的根节点;字符串exp保存逆波兰表达式;count保存exp中字符的个数;后序遍历中,处理根结点时,依据T->len的值,把T->data中的字符依次添加到当前exp字符串的尾端添加完T->data后,再添加一个空格字符,同时更新count计数器的值。
if(T)
{
PostOrderTraverse(T->lchild,exp,count);
PostOrderTraverse(T->rchild,exp,count);
strncpy(exp+count,T->data,T->len);
exp[count+=(T->len)]='';
count++;
}
}
//逆波兰表达式计算填空
StatusInitStack(SqStack&S)
{
S.base=(SElemtype*)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
if(!
S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
//printf("程序运行到构建栈\n");
returnOK;
}
intStackLength(SqStackS)
{
returnS.top-S.base;
//printf("程序运行到获得堆栈元素的个数\n");
//获得堆栈元素的个数
}
StatusPush(SqStack&S,SElemtypee)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemtype*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemtype));
if(!
S.base)
exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
//printf("程序运行到入栈\n");
returnOK;
//入栈
}
StatusPop(SqStack&S,SElemtype&e)
{
if(S.top==S.base)
returnERROR;
e=*--S.top;
//printf("程序运行到出栈\n");
returnOK;
//出栈
}
intEvalValue(char*ch,SqStack&S)
{
inti=0;
SElemtyperesult=0;
chara;
a=ch[i];
while(IsDigital(a))
{
result=10*result+(int)(a-48);
a=ch[++i];
}
Push(S,result);
//printf("程序运行标志1\n");
returni;
}
voidEvalExpr(charch,SqStack&S)
{
floatp,q,r;
if((ch=='+')||(ch=='-')||(ch=='*')||(ch=='/'))
{
Pop(S,p);
Pop(S,q);
switch(ch)
{
case'+':
r=p+q;
break;
case'-':
r=q-p;
break;
case'*':
r=q*p;
break;
case'/':
r=q/p;
break;
default:
;
}
Push(S,r);
//printf("程序运行标志2\n");
}
//如果ch中保存的是操作符,则从堆栈中弹出两个元素,并把操作符应用在这两个元素之上,然后把操作结果压入到栈中。
如果试图从栈中弹出两个元素是,该栈中并没有,那么该后缀表达式是不正确的。
}
Statusevaluate(charch[],float&result)
{
SqStackS;
StatusSt;
inti;
i=0;
St=InitStack(S);
while(ch[i]!
='#'&&i<100)
{
if(IsDigital(ch[i]))
{
i+=EvalValue(&ch[i],S);
}
elseif(ch[i]=='')
i++;
else{
EvalExpr(ch[i],S);
i++;
}
}
//如果到达表达式末尾时,栈中剩余元素不止一个,那么该
//后缀表达式是不正确的。
if(StackLength(S)==1)
Pop(S,result);
else{
//printf("表达式错误");
returnERROR;
}
//printf("程序运行标志3\n");
returnOK;
}
intmain()
{BiTreeT;
StatusSt;
charch[100],c;//输入的四则运算表达式
charexp[100];//逆波兰表达式
intcount=0;
inti=0;
floatresult;
printf("请输入表达式:
\n");
while(i<100)
{
scanf("%c",&c);
ch[i++]=c;
if(c=='\n'){
ch[--i]='#';
break;
}//endif
}
CrtExptree(T,ch);//根据字符串ch的内容构建表达式树T
//后序遍历表达式树T得到表达式的逆波兰表达式exp;count中保存exp中字符的个数
PostOrderTraverse(T,exp,count);
printf("逆波兰表达式为:
\n");
for(i=0;i printf("%c",exp[i]); printf("\n"); exp[count]='#';//添加结束符 St=evaluate(exp,result);//计算逆波兰表达式exp的值 //输出计算的结果 if(St) printf("运算结果: %5.2f\n",result); else printf("\n表达式错误\n"); return0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 四则运算 表达式 求值
![提示](https://static.bdocx.com/images/bang_tan.gif)