表达式求值实验报告.docx
《表达式求值实验报告.docx》由会员分享,可在线阅读,更多相关《表达式求值实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
![表达式求值实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/21/b1af4145-b93f-4340-8045-62b8057072d8/b1af4145-b93f-4340-8045-62b8057072d81.gif)
表达式求值实验报告
数据结构
课程设计报告
班级
姓名:
学号:
2009年12月17日
目录
1需求分析3
2概要设计3
3详细设计6
4测试与分析6
5总结7
6附录7
1需求分析
1、问题描述
用栈来实现表达式求值
2、基本要求
(1) 输入的形式:
可以输入数字、“+”“-”“*”“/”以及与其匹配的“(”“)”“[”“]”“{”“}”;
(2) 输出的形式:
直接输出数字答案;
(3) 程序所能达到的功能:
一般的四则混合运算;
2概要设计
1、数据结构
用2个栈进行运算,其中一个栈用来进行运算符存储及运算,另一个栈用来进行数字的存储及运算。
栈的概念:
栈(stack)是限定仅在表尾进行插入或删除操作的线性表。
其特点为先进后出。
ADTStack{
数据对象:
D={ai∣ai∈ElemSet,i=1,2,```,n,n≥0}
数据关系:
R1={<ai-1,ai>∣ai-1,ai∈D,I=2,```,n
约定an端为栈顶,a1端为栈底。
基本操作:
InitStack(&S)
操作结果:
构造一个空栈S。
DestroyStack(&S)
初始条件:
栈S已存在。
操作结果:
栈S被销毁。
ClearStack(&S)
初始条件:
栈S已存在。
操作结果:
栈S清为空栈。
StackEmpty(S)
初始条件:
栈S已存在。
操作结果:
若栈S为空栈,则返回TRUE,否则FALSE。
StackLength(S)
初始条件:
栈S已存在。
操作结果:
返回S的元素个数,即栈的长度。
GetTop(S,&e)
初始条件:
栈S已存在且非空。
操作结果:
用e返回S的栈顶元素。
Push(&S,e)
初始条件:
栈S已存在。
操作结果:
插入元素e为新的栈顶元素。
Pop(&S,e)
初始条件:
栈S已存在且非空。
操作结果:
删除S的栈顶元素,并用e返回其值。
StackTraverse(S,visit())
初始条件:
栈S已存在且非空。
操作结果:
从栈底到栈顶依次对S的每个数据元素调用函数visit()。
一旦visit()失败,则操作失效。
}ADTStack
2、程序模块
(1)voidF_push(Fnode*h,charc)
{
Fnode*p;
p=(Fnode*)malloc(sizeof(Fnode));
p->fh=c;
p->next=NULL;
if(c=='+'||c=='-')
p->yxj=1;
elseif(c=='*'||c=='/')
p->yxj=2;
elseif(c=='('||c==')')
p->yxj=0;
else
{free(p);return;}
while(h->next!
=NULL)
h=h->next;
p->next=h->next;
h->next=p;
}
(2)charF_pop(Fnode*h)
{
charc;
while(h->next->next!
=NULL)
h=h->next;
c=h->next->fh;
free(h->next);
h->next=NULL;
returnc;
}
intF_look(Fnode*h)
{
while(h->next!
=NULL)
h=h->next;
returnh->yxj;
}
(3)voidS_push(Snode*h,doublec)
{
Snode*p;
p=(Snode*)malloc(sizeof(Snode));
p->data=c;
p->next=NULL;
while(h->next!
=NULL)
h=h->next;
p->next=h->next;
h->next=p;
}
(4)doubleS_pop(Snode*h)
{
doublei;
while(h->next->next!
=NULL)
h=h->next;
i=h->next->data;
free(h->next);
h->next=NULL;
returni;
}
3、各模块之间的调用关系以及算法设计
main()
{
Fnode*fh;
Snode*sh;
char*str;
printf("请输入表达式,按回车之后输出结果:
");
fh=(Fnode*)malloc(sizeof(Fnode));
fh->next=NULL;
sh=(Snode*)malloc(sizeof(Snode));
sh->next=NULL;
str=change(gets(str));
printf("=%lf",final(str,fh,sh));
getch();
}
3详细设计
OperandTypeEvauateExpression(){
Initstack(OPTR);Push(OPTR,‘#’);
initStack(OPND);c=getchar();
while(c!
=‘#’||GetTop(OPTR)!
=‘#’){
if(In(c,OP)){Push(OPND,c);c=getchar();}
else
switch(Precede(GetTop(OPTR);c)){
case‘<’:
Push(OPTR,c);c=getchar();
breake;
Case‘=’:
Pop(OPTR,x);c=getchar();
Breake;
Case‘>’:
Pop(OPTR,theta);
Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
}//switch
}//while
TeturnGetTop(OPND);
}
4测试与分析
(1)运行页面
请输入表达式,按回车后输出结果
(2)运行检测
输入“1+1”,按“回车”后输出“2.000000”
说明加减运算可以进行
输入“2*3”,按“回车”后输出“6.000000”
说明乘除运算可以进行
输入“1+2*3”,按“回车”后输出“7.000000”
说明加减乘除混合运算可以进行
输入“(1+2)*3+4”,按“回车”后输出“13.000000”
说明带括号的混合运算可以进行
程序可以进行。
5总结
经过此次数据结构课程设计是我对数据结构有了更深一步的认识,在编程过程中我既体验到了编程成功所带来的喜悦,也体会到了在编程过程中遇到的问题给我带来的烦恼。
一个小错误会导致一个花费了很长时间和心思编出来的程序无法运行。
此次编程是我了解到学习知识的扎实性和编程的细心是很重要的,与此同时我也发现在自己程序出现问题而有无法发现时,虚心向他人求教也是必要的。
我将会在以后的编程过程中努力改正自己的缺点,不断完善自己。
6附录
#include
#include
#include
typedefstructFnode/*符号单链表*/
{
intyxj;
charfh;
structFnode*next;
}Fnode;
voidF_push(Fnode*h,charc)/*对运算符号的入栈操作*/
{
Fnode*p;
p=(Fnode*)malloc(sizeof(Fnode));
p->fh=c;
p->next=NULL;
if(c=='+'||c=='-')
p->yxj=1;
elseif(c=='*'||c=='/')
p->yxj=2;
elseif(c=='('||c==')')
p->yxj=0;
else
{free(p);return;}
while(h->next!
=NULL)
h=h->next;
p->next=h->next;
h->next=p;
}
charF_pop(Fnode*h)/*对运算符号的出栈操作*/
{
charc;
while(h->next->next!
=NULL)
h=h->next;
c=h->next->fh;
free(h->next);
h->next=NULL;
returnc;
}
intF_look(Fnode*h)
{
while(h->next!
=NULL)
h=h->next;
returnh->yxj;
}
/*------------------------------------------------------------*/
typedefstructSnode/*数字单链表*/
{
doubledata;
structSnode*next;
}Snode;
voidS_push(Snode*h,doublec)/*对数字的入栈操作*/
{
Snode*p;
p=(Snode*)malloc(sizeof(Snode));
p->data=c;
p->next=NULL;
while(h->next!
=NULL)
h=h->next;
p->next=h->next;
h->next=p;
}
doubleS_pop(Snode*h)/*对数字的出栈操作*/
{
doublei;
while(h->next->next!
=NULL)
h=h->next;
i=h->next->data;
free(h->next);
h->next=NULL;
returni;
}
/*-------------------------------------------------------*/
char*change(char*str)/*字符串前加(,后加)*/
{
char*r;
*(str-1)='(';
str--;
r=str;
strcat(r,")");
returnr;
}
/*;-------------------------------------------------*/
doublefinal(char*str,Fnode*fh,Snode*sh)/*计算表达式结果*/
{
doublei,temp,emp;
while(*str!
='\0')
{
if(*str=='(')
{
F_push(fh,*str);
str++;
continue;
}
elseif(*str>='0'&&*str<='9')
{
emp=0;
while(*str>='0'&&*str<='9')
{
emp=emp*10+(*str-'0');
str++;
}
S_push(sh,emp);
continue;
}
elseif(*str=='.')
{
i=0.1;str++;emp=0;
if(*str>='0'&&*str<='9')
{
while(*str>='0'&&*str<='9')
{
emp+=(*str-'0')*i;
i*=0.1;
str++;
}
S_push(sh,(S_pop(sh)+emp));
}
}
elseif(*str==')')
{
while(F_look(fh)!
=0)
{
switch(F_pop(fh))
{
case'+':
emp=S_pop(sh);S_push(sh,(S_pop(sh)+emp));break;
case'-':
emp=S_pop(sh);S_push(sh,(S_pop(sh)-emp));break;
case'*':
emp=S_pop(sh);S_push(sh,(S_pop(sh)*emp));break;
case'/':
emp=S_pop(sh);S_push(sh,(S_pop(sh)/emp));break;
default:
;
}
}
F_pop(fh);
str++;
continue;
}
else
{
if(*str=='+'||*str=='-')
temp=1;
else
temp=2;
if(temp>F_look(fh))
F_push(fh,*str);
else
{
switch(F_pop(fh))
{
case'+':
emp=S_pop(sh);S_push(sh,(S_pop(sh)+emp));break;
case'-':
emp=S_pop(sh);S_push(sh,(S_pop(sh)-emp));break;
case'*':
emp=S_pop(sh);S_push(sh,(S_pop(sh)*emp));break;
case'/':
emp=S_pop(sh);S_push(sh,(S_pop(sh)/emp));break;
default:
;
}
F_push(fh,*str);
}
str++;continue;
}
}
returnS_pop(sh);
}
main()
{
Fnode*fh;
Snode*sh;
char*str;
printf("请输入表达式,按回车之后输出结果:
");
fh=(Fnode*)malloc(sizeof(Fnode));
fh->next=NULL;
sh=(Snode*)malloc(sizeof(Snode));
sh->next=NULL;
str=change(gets(str));
printf("=%lf",final(str,fh,sh));
getch();
}