完整word版顺序栈基本操作实验报告.docx
《完整word版顺序栈基本操作实验报告.docx》由会员分享,可在线阅读,更多相关《完整word版顺序栈基本操作实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
完整word版顺序栈基本操作实验报告
数据构造
实验三
课程
数据构造
实验名称
序次栈根本操作
第
页
专业
班级
学号
姓名
实验日期:
年月日
评分
一、实验目的
1.熟悉并能实现栈的定义和根本操作。
2.认识和掌握栈的应用。
二、实验要求
1.进行栈的根本操作时要注意栈"后进先出"的特点。
2.编写完满程序完成下面的实验内容并上机运行。
3.整理并上交实验报告。
三、实验内容
1.编写程序任意输入栈长度和栈中的元素值,构造一个序次栈,对其进行清空、销毁、入栈、出栈以及取栈顶元素操作。
2.编写程序实现表达式求值,即考据某算术表达式的正确性,假设正确,那么计算该算术表达式的值。
主要功能描述以下:
(1〕从键盘上输入表达式。
(2〕解析该表达式可否合法:
a)是数字,那么判断该数字的合法性。
假设合法,那么压入数据到货仓中。
b)是规定的运算符,那么依照规那么进行办理。
在办理过程中,将计算该表达式的值。
c)假设是其他字符,那么返回错误信息。
(3〕假设上述办理过程中没有发现错误,那么认为该表达式合法,并打印办理结果。
程序中应主要包含下面几个功能函数:
lvoidinitstack():
初始化货仓
lintMake_str():
语法检查并计算
lintpush_operate(intoperate):
将操作码压入货仓
lintpush_num(doublenum):
将操作数压入货仓
lintprocede(intoperate):
办理操作码
lintchange_opnd(intoperate):
将字符型操作码变换成优先级
lintpush_opnd(intoperate):
将操作码压入货仓
lintpop_opnd():
将操作码弹出货仓
lintcaculate(intcur_opnd):
简单计算+,-,*,/
ldoublepop_num():
弹出操作数
四、实验步骤
〔描述实验步骤及中间的结果或现象。
在实验中做了什么事情,怎么做的,发生的现象和中间结果〕
第一题:
#include
usingnamespacestd;
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineOVERFLOW-1
#defineOK1
#defineNO-1
#defineNULL0
typedefintStatus;
typedefcharSElemType;
typedefstruct
{
//储藏空间初始分配量
//储藏空间分配增量
SElemType*base;SElemType*top;
//在栈构造从前和销毁此后,//栈顶指针
base的值为
NULL
intstacksize;
//当前已分配的储藏空间,以元素为单位
}SqStack;
StatusInitstack(SqStack&S)//构造一个空栈S
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!
S.base)
exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}//InitStack
StatusStackEmpty(SqStack&S)
{
if(S.base==S.top)
returnOK;
else
returnNO;
}
StatusClearStack(SqStack&S)//把S置为空
{
if(S.base=S.top);
returnOK;
}
StatusDsetroyStack(SqStack&S)//销毁栈S
{
S.base=NULL;
returnOK;
}
StatusPush(SqStack&S,SElemTypee)
//插入元素e为新的栈顶元素
{
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;
returnOK;
}//Push
StatusPop(SqStack&S,SElemType&c)
//假设栈不空,那么删除S的栈顶元素,用c返回其值,并返回OK;否那么返回ERROR
{
if(S.top==S.base)
returnNO;
c=*--S.top;
returnOK;
}//Pop
StatusGetTop(SqStack&S,SElemType&e)
{
if(S.top==S.base)
returnNO;
e=*(S.top-1);
returnOK;
}//GetTop
intmain()
{
SqStackS;
Initstack(S);
cout<<"输入要压到栈中的元素!
"<charc;
while((c=getchar())!
='\n')
{
Push(S,c);
}
GetTop(S,c);
cout<<"栈顶元素为:
"<//ClearStack(S);
//DsetroyStack(S);
for(inti=0;S.top!
=S.base;i++)
{
Pop(S,c);
cout<<"栈中第"<
";
cout<}
return0;
}
第二题:
#include
usingnamespacestd;
#defineSTACK_SIZE100
#defineSTACKINCREMENT10
#defineOVERFLOW-1
#defineOK1
#defineNO0
typedefintStatus;
typedefcharSElemType;
typedefstruct
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
intmain()
{
charGetTop(SqStack&s);
StatusInitstack(SqStack&s);
Statuspush_operate(SqStack&s,SElemTypee);
Statuspush_num(SqStack&s,inte);
StatusStackempty(SqStack&s);
Statuspop_num(SqStack&s,int&c);
Statuspushoperate(SElemTypeoperate);
Statuspushnum(SElemTypenum);
Statuscaculate(SElemTypea,SElemTypeoperate,SElemTypeb);Statuspop_operate(SqStack&s,SElemType&c);
Statuschange(SElemTypee);
charPrecede(SElemTypea,SElemTypeb);
charOperatecxz();
intm;
m=Operatecxz();
cout<return0;
}
Statuschange(SElemTypee)
{
intm;
m=e-48;
returnm;
}
StatusInitstack(SqStack&s)
{
s.base=(SElemType*)malloc(STACK_SIZE*sizeof(SElemType));if(!
s.base)
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_SIZE;
returnOK;
}
StatusStackempty(SqStack&s)
{
if(s.base==s.top)
returnOK;
else
returnNO;
}
Statuspush_num(SqStack&s,inte)
{
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;
returnOK;
}
Statuspush_operate(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;
returnOK;
}
Statuspop_operate(SqStack&s,SElemType&c)
{
if(s.top==s.base)
returnNO;
c=*--s.top;
returnOK;
}
Statuspop_num(SqStack&s,int&c)
{
if(s.top==s.base)
returnNO;
c=*--s.top;
returnOK;
}
charGetTop(SqStack&s)
{
charc;
if(s.top==s.base)
returnNO;
c=*(s.top-1);
returnc;
}
Statuscaculate(inta,SElemTypeoperate,intb)
{
ints;
if(operate=='+')
s=a+b;
if(operate=='-')
s=a-b;
if(operate=='*')
s=a*b;
if(operate=='/')
s=a/b;
returns;
}
StatusIn(SElemTypec)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')')
returnOK;
if(c>='0'&&c<='9')
returnNO;
return-1;
}
charPrecede(SElemTypea,SElemTypeb)
{
if(a=='+'||a=='-')
{
if(b=='+'||b=='-'||b==')'||b=='#')
return'>';
if(b=='*'||b=='/'||b=='(')
return'<';
}
if(a=='*'||a=='/')
{
if(b=='+'||b=='-'||b==')'||b=='*'||b=='/'||b=='#')
return'>';
if(b=='(')
return'<';
}
if(a=='(')
{
if(b==')')
return'=';
if(b=='+'||b=='-'||b=='*'||b=='/')
return'<';
if(b=='#')
return'';
}
if(a==')')
{
if(b==')')
return'';
if(b=='+'||b=='-'||b=='*'||b=='/'||b=='('||b=='#')
return'>';
}
if(a=='#')
{
if(b=='#')
return'=';
if(b=='+'||b=='-'||b=='*'||b=='/'||b=='(')
return'<';
if(b==')')
return'';
}
return'';
}
charOperatecxz()
{
SqStackOperate,Num;
charc,e,x;
intnum,a,b,flat=1,sz=0;
Initstack(Operate);
push_operate(Operate,'#');
Initstack(Num);
c=getchar();
while(c!
='#'||GetTop(Operate)!
='#')
{
if(In(c)==-1)
{
cout<<"inputerror!
"<flat=0;
break;
}
if(In(c)!
=1)
{
if(sz==0)
{
num=change(c);
sz=1;
c=getchar();
continue;
}
if(sz==1)
num=num*10+change(c);
c=getchar();
continue;
}
else
{
if(sz==1)
push_num(Num,num);
sz=0;
x=GetTop(Operate);
switch(Precede(GetTop(Operate),c))
{
case'<':
{
push_operate(Operate,c);
c=getchar();
break;
}
case'=':
{
pop_operate(Operate,e);
c=getchar();
break;
}
case'>':
{
pop_num(Num,a);
pop_operate(Operate,e);
pop_num(Num,b);
push_num(Num,caculate(b,e,a));
break;
}
}
}
}
pop_operate(Operate,e);
if(e!
='#')
flat=0;
if(flat==1)
{
pop_num(Num,a);
returna;
}
if(flat==0)
return0;
}
五.实验结果与谈论
〔描述最后获取的结果,并进行解析说明,可能的误差原因〕
第一题:
1把主函数中的ClearStack(S);DsetroyStack(S)说明掉的结果:
2不把ClearStack(S)说明掉,把栈清空:
3不把DsetroyStack(S)说明掉,即销毁栈:
出现一堆乱码,说明销毁成功。
第二题的输出:
1正常输入表达式那么输出:
2若是输入的表达式出错那么输出:
六.实验总结:
1在写主函数时,若是是用voidmain的形式,那么可以不用有返回值,若是是intmain或
|statusmain的话,要有返回值,既尾端要有return语句。
2有时写的没有出现问题,但运行的结果是Pressanukeytocontinue。
程序必然有错,但
为什么会出现这种问题呢。
3分号的忘记那还是很经常的,要加强注意。
4原本把ClearStack(S);DsetroyStack(S)放在for循环之后,检查不出ClearStack
(S);DsetroyStack(S)的函数可否正确。
把它们for循环从前,GetTop(S,c)语句此后,再利用说明等的,就可以很明显的看出栈可否被清空或销毁。
5在做表达式的计算的时候必然要注意何时入栈何时出栈。
若是如栈与出栈的情况判断不清楚就无法得出答案。
6在定义栈的时候Num中的元素最好使用int种类的而不是char种类的。
因为这样会简化charOperatecxz()的计算复杂度。
7对于表达式的判错情况,依照题目中的提示对每次读入的字符进行判断。
8对于不是个位数的计算,第一用了个
Statuschange(SElemTypee)
{
intm;
m=e-48;
returnm;
}
把每个字符转变为int型,尔后再用sz作为标记直到读入的数不是数字为止。
此时再将从前读入的数num压入Num栈中。
9对于优先级的判断依照书上给定的表格进行建立关系。
注意优先级的判断为这个实验最为要点的,也是最需要认真的地方。
只要有一个地方弄错,将以致整个实验都出错。