数据结构实验二.docx
- 文档编号:11615494
- 上传时间:2023-03-28
- 格式:DOCX
- 页数:20
- 大小:103.69KB
数据结构实验二.docx
《数据结构实验二.docx》由会员分享,可在线阅读,更多相关《数据结构实验二.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构实验二
《数据结构与算法统计》
实验报告
专业:
班级:
学号:
姓名:
一、实验目的
1.学习使用C++实现栈的存储结构;.通过编程、上机调试,进一步理解栈的基本概念;
2.锻炼独立编程与思考的能力,提升实践能力。
二、实验内容
简单计算器。
请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。
要求:
③从键盘输入一个完整的表达式,以回车作为表达式输入结束的标志。
④输入表达式中的数值均为大于等于零的整数。
中间的计算过程如果出现小数也只取整。
例如,输入:
4+2*5=输出:
14
输入:
(4+2)*(2-10)=输出:
-48
三、程序设计
1、概要设计
为实现上述功能,应该使用两个栈,分别寄存操作数和运算符。
为此需要栈的抽象数据结构。
⑴栈的抽象数据类型定义如下:
ADTStack{
数据对象:
D={ai|aiÎElemSet,i=1,…,n,n≥0}
数据关系:
R1={
基本操作:
InitStack1(SqStack1&S)
操作结果:
创建一个空栈S,以存储运算符
InitStack2(SqStack2&S)
操作结果:
创建一个空栈S,以存储操作数
Push1(SqStack1&S,chare)
初始条件:
栈S已存在
操作结果:
插入运算符e作为新的栈顶元素
Push2(SqStack2&S,inte)
初始条件:
栈S已存在
操作结果:
插入操作数e作为新的栈顶元素
Precede(chard,charc)
初始条件:
d,c为运算符
操作结果:
若d优先级大于c,返回>;若d优先级小于c,返回<;若d优先级等于c,返回=;
GetTop1(SqStack1&S)
初始条件:
栈S已存在且非空
操作结果:
用e返回寄存运算符栈S的栈顶元素
GetTop2(SqStack2&S)
初始条件:
栈S已存在且非空
操作结果:
用e返回寄存操作数栈S的栈顶元素
Pop1(SqStack1&S,char&e)
初始条件:
栈S已存在且非空
操作结果:
删除寄存运算符栈S的栈顶元素
Pop2(SqStack2&S,int&e)
初始条件:
栈S已存在且非空
操作结果:
删除寄存操作数栈S的栈顶元素
Operate(inta,chartheta,intb)
初始条件:
a,b为整数,theta为运算符
操作结果:
返回a与b运算的结果
Yunsuan()
初始条件:
输入合法的表达式
操作结果:
返回表达式的值
}ADTStack
⑵主程序流程
调用Yunsuan()函数计算表达式的值,输出,在屏幕上打印出来。
⑶各模块的调用关系
先由主函数调用计算求值模块;再由求值模块调用栈构造模块,表达式转换模块及表达式求值模块,计算并返回表达式的值;最后由主函数在屏幕上输出表达式的结果。
⑷流程图
2、详细设计
⑴数据类型设计
typedefstruct{
char*base;
char*top;
intstacksize;
}SqStack1;//定义运算符栈数据类型
typedefstruct{
int*base;
int*top;
intstacksize;
}SqStack2;//定义操作数栈数据类型
⑵操作算法设计
intInitStack1(SqStack1&S)//构造运算符栈
{S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));//申请存储空间
if(!
S.base)exit(OVERFLOW);//存储空间分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
intInitStack2(SqStack2&S)//构造操作数栈
{S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));//申请存储空间
if(!
S.base)exit(OVERFLOW);//存储空间分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
charGetTop1(SqStack1&S)//取得运算符栈栈顶元素
{chare;
if(S.top==S.base)//栈空
{return0;
}
e=*(S.top-1);
returne;
}
intGetTop2(SqStack2&S)//取得操作数栈栈顶元素
{chare;
if(S.top==S.base)//栈空
{
return0;
}
e=*(S.top-1);
returne;
}
intPush1(SqStack1&S,chare)//插入元素e作为运算符栈栈顶元素
{if(S.top-S.base>=S.stacksize)//栈满,追加存储空间
{S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!
S.base)exit(OVERFLOW);//分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPush2(SqStack2&S,inte)//插入元素e作为操作数栈栈顶元素
{if(S.top-S.base>=S.stacksize)//栈满,追加存储空间
{S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));
if(!
S.base)exit(OVERFLOW);//分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPop1(SqStack1&S,char&e)//删除运算符栈栈顶元素,并用e返回
{if(S.top==S.base)//栈空
{return0;
}
--S.top;
e=*S.top;
return1;
}
intPop2(SqStack2&S,int&e)//删除运算符栈栈顶元素,并用e返回
{if(S.top==S.base)//栈空
{return0;
}
--S.top;
e=*S.top;
return1;
}
charPrecede(chard,charc)//判断d与c的优先级
{switch(c)
{case'+':
switch(d)
{case'+':
return'>';break;
case'-':
return'>';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'-':
switch(d)
{case'+':
return'>';break;
case'-':
return'>';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'*':
switch(d)
{case'+':
return'<';break;
case'-':
return'<';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'/':
switch(d)
{case'+':
return'<';break;
case'-':
return'<';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'^':
switch(d)
{case'+':
return'<';break;
case'-':
return'<';break;
case'*':
return'<';break;
case'/':
return'<';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'(':
switch(d)
{case'+':
return'<';break;
case'-':
return'<';break;
case'*':
return'<';break;
case'/':
return'<';break;
case'^':
return'<';break;
case'(':
return'<';break;
case'=':
return'<';break;
}
case')':
switch(d)
{case'+':
return'>';break;
case'-':
return'>';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'=';break;
case')':
return'>';break;
}
case'=':
switch(d)
{case'+':
return'>';break;
case'-':
return'>';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case')':
return'>';break;
case'=':
return'=';break;
}
}
}
intOperate(inta,chartheta,intb)//运算函数
{switch(theta)
{case'+':
return(a+b);
case'-':
return(a-b);
case'*':
return(a*b);
case'/':
return(a/b);
case'^':
return(pow(a,b));
}
}
intYunsuan()//主要运算函数
{charc,d,theta,x;
intnum,a,b;
SqStack1OPTR;
SqStack2OPND;
InitStack1(OPTR);//构造运算符栈
InitStack2(OPND);//构造操作数栈
Push1(OPTR,'=');
c=getchar();
while(c!
='='||GetTop1(OPTR)!
='=')
{num=0;
if(c!
='+'&&c!
='-'&&c!
='*'&&c!
='/'&&c!
='^'&&c!
='('&&c!
=')'&&c!
='=')//不是运算符进入操作数栈
{while(c!
='+'&&c!
='-'&&c!
='*'&&c!
='/'&&c!
='^'&&c!
='('&&c!
=')'&&c!
='=')//将输入的操作数的字符型转换为整型
{num*=10;
num+=(c-48);
c=getchar();
}
Push2(OPND,num);
}
else//若是运算符
{
d=GetTop1(OPTR);
switch(Precede(d,c))//运算符优先级比较
{case'<':
Push1(OPTR,c);c=getchar();break;//栈顶运算符优先级低,新输入的运算符进栈
case'=':
Pop1(OPTR,x);c=getchar();break;//去括号case'>':
Pop1(OPTR,theta);Pop2(OPND,b);Pop2(OPND,a);Push2(OPND,Operate(a,theta,b));break;
//运算,并将运算结果放入操作数栈
}
}
returnGetTop2(OPND);//返回操作数栈栈顶元素
}
⑶主函数设计
voidmain()
{intp;
p=Yunsuan();//进行计算
printf("%d\n",p);//输出结果
}
四、程序调试分析
1.刚开始时没有思路,后来回顾了一下课上学习的内容,有所启发,认识到解决该问题需要设计两个栈;
2.自己在编写时,容易输错字符,有时候不易发现,很麻烦,仔细程度还有待提高,还需要多进行编程练习;
五、用户使用说明
运行程序,输入运算表达式,以“=”结束,然后敲击回车键,即可输出表达式的运算结果。
六、程序运行结果
1、输入:
4+2*5=输出:
14
2、输入:
(4+2)*(2-10)=输出:
-48
3、输入:
(4/3-2)*(2-6)=输出:
4
七、程序清单
#include
#include
#include
#include
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT20
typedefstruct
{
char*base;
char*top;
intstacksize;
}SqStack1;//定义运算符栈数据类型
typedefstruct
{
int*base;
int*top;
intstacksize;
}SqStack2;//定义操作数栈数据类型
intInitStack1(SqStack1&S);
intInitStack2(SqStack2&S);
intPush1(SqStack1&S,chare);
intPush2(SqStack2&S,inte);
charPrecede(chard,charc);
charGetTop1(SqStack1&S);
intGetTop2(SqStack2&S);
intPop1(SqStack1&S,char&e);
intPop2(SqStack2&S,int&e);
intOperate(inta,chartheta,intb);
intYunsuan();
intYunsuan()//设计主要运算函数
{
charc,d,theta,x;
intnum,a,b;
SqStack1OPTR;
SqStack2OPND;
InitStack1(OPTR);//构造运算符栈
InitStack2(OPND);//构造操作数栈
Push1(OPTR,'=');
c=getchar();
while(c!
='='||GetTop1(OPTR)!
='=')
{num=0;
if(c!
='+'&&c!
='-'&&c!
='*'&&c!
='/'&&c!
='^'&&c!
='('&&c!
=')'&&c!
='=')
//若不是运算符进入操作数栈
{
while(c!
='+'&&c!
='-'&&c!
='*'&&c!
='/'&&c!
='^'&&c!
='('&&c!
=')'&&c!
='=')
//将输入的操作数的字符型转换为整型
{
num*=10;
num+=(c-48);
c=getchar();
}
Push2(OPND,num);
}
else//若是运算符
{d=GetTop1(OPTR);
switch(Precede(d,c))//运算符优先级比较
{
case'<':
Push1(OPTR,c);c=getchar();break;
//栈顶运算符优先级低,新输入的运算符进栈
case'=':
Pop1(OPTR,x);c=getchar();break;//去括号
case'>':
Pop1(OPTR,theta);
Pop2(OPND,b);
Pop2(OPND,a);
Push2(OPND,Operate(a,theta,b));
break;//运算,并将运算结果放入操作数栈
}
}
}
returnGetTop2(OPND);//返回操作数栈栈顶元素
}
intInitStack1(SqStack1&S)//构造运算符栈
{S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));//申请存储空间
if(!
S.base)exit(OVERFLOW);//存储空间分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
intInitStack2(SqStack2&S)//构造操作数栈
{
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));//申请存储空间
if(!
S.base)exit(OVERFLOW);//存储空间分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return1;
}
charGetTop1(SqStack1&S)//取得运算符栈栈顶元素
{
chare;
if(S.top==S.base)//若是栈空
{
return0;
}
e=*(S.top-1);
returne;
}
intGetTop2(SqStack2&S)//取得操作数栈栈顶元素
{
chare;
if(S.top==S.base)//若是栈空
{
return0;
}
e=*(S.top-1);
returne;
}
intPush1(SqStack1&S,chare)//插入元素e作为运算符栈栈顶元素
{if(S.top-S.base>=S.stacksize)//栈满,追加存储空间
{
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!
S.base)exit(OVERFLOW);//分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPush2(SqStack2&S,inte)//插入元素e作为操作数栈栈顶元素
{if(S.top-S.base>=S.stacksize)//栈满,追加存储空间
{S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));
if(!
S.base)exit(OVERFLOW);//分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return1;
}
intPop1(SqStack1&S,char&e)//删除运算符栈栈顶元素,并用e返回
{if(S.top==S.base)//若是栈空
{
return0;
}
--S.top;
e=*S.top;
return1;
}
intPop2(SqStack2&S,int&e)//删除运算符栈栈顶元素,并用e返回
{if(S.top==S.base)//若是栈空
{
return0;
}
--S.top;
e=*S.top;
return1;
}
charPrecede(chard,charc)//判断d与c的优先级
{switch(c)
{
case'+':
switch(d)
{case'+':
return'>';break;
case'-':
return'>';break;
case'*':
return'>';break;
case'/':
return'>';break;
case'^':
return'>';break;
case'(':
return'<';break;
case')':
return'>';break;
case'=':
return'<';break;
}
case'-':
switch(d)
{case'+':
return'>';break;
case'-':
ret
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验