数据结构课程设计表达式求值问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.2
本次试验中内存出错的情况比较多,比如在输出后缀表达式时虽然结果正确,但后面还有很多“烫烫…”,在计算后缀表达式时,返回值总是没有,等等,但通过不断地调试这些问题都得以解决。
通过本次实验,加强了对栈和队列的存储结构的理解,尤其是栈的先进后出的结构有了更深的了解。
参考文献
[1]苏仕华等.数据结构课程设计.机械工业出版社.2005.05
case '+'||case '-'||case '*'||case '/':
while (Priority(c)<=Priority(GetTop(S)))//比较优先级
EnQueue(Q,Pop(S))
Push(S,c)
}
4.1.1
算术运算符入栈时必须考虑运算符的优先级,才能形成正确的后缀表达式,当读到运算符时,将栈中所有优先级高于或等于该运算符的运算符弹出,送至输出队列中,再将当前运算符入栈;当读入左括号时,即入栈;当读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列中,再删除栈中的左括号。
图4.1.1后缀表达式的转换
其伪代码算法如下:
switch(c){
case '0'tocase '9':EnQueue(Q,c)
case '(':Push(S,c)
case ')'to case'#':t=Pop(S);
if (t!='(' && t!='#')
EnQueue(Q,t);
} while (t!='(' && S->top!=-1);
通过返回值的大小代表优先级的大小,其伪代码算法如下:
switch (op){
case '('||case'#':return 0;break;
case '-'||case '+':return 1;break;
case '*'||case '/':return 2;break;
}
4.1.2
当中缀表达式转换成后缀表达式之后,需要输出后缀表达式,也就是当前队列,只需要让头指针遍历输出数据即可。
3中缀表达式转换为后缀表达式时为什么要用Push(S,'#')将#压入栈底?
4后缀表达式的求值中,SeqStack vs的作用是什么?为什么不用vs会出错?
5调用后缀表达式进行计算时,最终计算结果是放在栈中的,但为什么返回栈顶元素时总是指向空?因为之前调用了Dequeue(Q),导致front发生了改变,相当于队列被删除了,所以再调用时就为空了,解决方法有多种,比如复制队列,我采取了一个简单的方法,在调用了CTPostExp(Q)后不忙着输出后缀表达式,继续调用CPostExp(Q),在CPostExp(Q)中使用Dequeue(Q)时顺便就将后缀表达式输出,这样就避免了队列第二次调用时已经被删除的窘境。
1概述
1.1
我们在很早的时候就开始学习书写及计算表达式,可以说运用起来很熟练了,但有时候并不想自己计算,交给计算器是时有的事,然而普通的计算器并不懂得优先级,给计算带来了一定的不便。
本程序实现的目的是将人们习惯的中缀表达式转换为计算机所能理解的后缀表达式以方便计算,最终得出我们所需要的正确的答案。
2百度文库
[2]严蔚敏,吴伟明.数据结构(C语言版).清华大学出版社.2007
[3]谭浩强. C程序设计(第三版).清华大学出版社. 2005
附加程序代码:
#include<stdio.h>
#define StackSize 100
#define QueueSize 100
typedef char DataType;
typedef struct
{
char data[100];
int front,rear;
}SeqQueue;//定义队列类型
typedef struct
{
DataType data[100];
int top;
}SeqStack;//栈类型的定义
//初始化队列
void InitQueue(SeqQueue * Q)
图3.1.1系统总体结构图
3.2
本程序所用的数据结构类型是栈和队列。
首先提示用户输入中缀表达式,再利用程序将中缀表达式转换为后缀表达式,其中数字入队列,算术运算符入栈。
图3.2.1程序算法图
4
4.1
将中缀表达式转换为后缀表达式首先需要扫描中缀表达式,当遇到数字时,将其入队列,当遇到运算符时,若是低优先级则直接入栈,若是高优先级则将低优先级运算符弹出,并入队列,再将此次运算符入栈,最终形成后缀表达式
if (ch>='0' && ch<='9')
Push(S,ch-'0';)//数字字符到数值的转换
else{
y=Pop(S),x=Pop(S)
switch (ch){
case '+':Push(S,x+y);break;
case '-':Push(S,x-y);break;
case '*':Push(S,x*y);break;
case '/':Push(S,x/y);break;
}
}
5
5.1
输入一个中缀表达式:
5.2
输出后缀表达式及其结果:
6
6.1
在本次实验中,遇到的心得:
1为什么有判空队列不需要判空栈?因为当S->top=-1时栈变为空,不需要单独写一个函数出来判断。
2后缀表达式的求值中,Push(S,ch-'0')中的ch-‘0’是什么意思?因为输入表达式时数字是以字符的形式存储的,当进行计算式需要字符到数值的转换。
2.1
当我们需要进行一长串的计算时,各种运算符夹杂在一起,通过笔算很容易得出结果。然而计算机并没有人脑那么聪明,它并不懂得先乘除后加减,有括号要先计算括号里面的,它只知道从左到右的进行计算,这就造成了计算机计算的失误,科学的计算是人们非常需要的计算工具。
3
3.1
整个系统结构如图3-1-1所示,结构非常清楚,程序顺序执行,首先提示用户输入需要计算的表达式,经过转换得到后缀表达式,最后结果将数据显示到主屏幕上即可。
{
Q->front=0;
其伪代码如下:
x=Q->data[Q->front++];
4.2
由于在将中缀表达式转换为后缀表达式时已经将运算符安排在了合适的位置,在后缀表达式中不仅不需要括号,而且还完全免除了运算符优先规则,仅需从左到右计算即可。
其伪代码如下:
while(!QueueEmpty(Q)){
ch=DeQueue(Q)
本次试验中内存出错的情况比较多,比如在输出后缀表达式时虽然结果正确,但后面还有很多“烫烫…”,在计算后缀表达式时,返回值总是没有,等等,但通过不断地调试这些问题都得以解决。
通过本次实验,加强了对栈和队列的存储结构的理解,尤其是栈的先进后出的结构有了更深的了解。
参考文献
[1]苏仕华等.数据结构课程设计.机械工业出版社.2005.05
case '+'||case '-'||case '*'||case '/':
while (Priority(c)<=Priority(GetTop(S)))//比较优先级
EnQueue(Q,Pop(S))
Push(S,c)
}
4.1.1
算术运算符入栈时必须考虑运算符的优先级,才能形成正确的后缀表达式,当读到运算符时,将栈中所有优先级高于或等于该运算符的运算符弹出,送至输出队列中,再将当前运算符入栈;当读入左括号时,即入栈;当读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列中,再删除栈中的左括号。
图4.1.1后缀表达式的转换
其伪代码算法如下:
switch(c){
case '0'tocase '9':EnQueue(Q,c)
case '(':Push(S,c)
case ')'to case'#':t=Pop(S);
if (t!='(' && t!='#')
EnQueue(Q,t);
} while (t!='(' && S->top!=-1);
通过返回值的大小代表优先级的大小,其伪代码算法如下:
switch (op){
case '('||case'#':return 0;break;
case '-'||case '+':return 1;break;
case '*'||case '/':return 2;break;
}
4.1.2
当中缀表达式转换成后缀表达式之后,需要输出后缀表达式,也就是当前队列,只需要让头指针遍历输出数据即可。
3中缀表达式转换为后缀表达式时为什么要用Push(S,'#')将#压入栈底?
4后缀表达式的求值中,SeqStack vs的作用是什么?为什么不用vs会出错?
5调用后缀表达式进行计算时,最终计算结果是放在栈中的,但为什么返回栈顶元素时总是指向空?因为之前调用了Dequeue(Q),导致front发生了改变,相当于队列被删除了,所以再调用时就为空了,解决方法有多种,比如复制队列,我采取了一个简单的方法,在调用了CTPostExp(Q)后不忙着输出后缀表达式,继续调用CPostExp(Q),在CPostExp(Q)中使用Dequeue(Q)时顺便就将后缀表达式输出,这样就避免了队列第二次调用时已经被删除的窘境。
1概述
1.1
我们在很早的时候就开始学习书写及计算表达式,可以说运用起来很熟练了,但有时候并不想自己计算,交给计算器是时有的事,然而普通的计算器并不懂得优先级,给计算带来了一定的不便。
本程序实现的目的是将人们习惯的中缀表达式转换为计算机所能理解的后缀表达式以方便计算,最终得出我们所需要的正确的答案。
2百度文库
[2]严蔚敏,吴伟明.数据结构(C语言版).清华大学出版社.2007
[3]谭浩强. C程序设计(第三版).清华大学出版社. 2005
附加程序代码:
#include<stdio.h>
#define StackSize 100
#define QueueSize 100
typedef char DataType;
typedef struct
{
char data[100];
int front,rear;
}SeqQueue;//定义队列类型
typedef struct
{
DataType data[100];
int top;
}SeqStack;//栈类型的定义
//初始化队列
void InitQueue(SeqQueue * Q)
图3.1.1系统总体结构图
3.2
本程序所用的数据结构类型是栈和队列。
首先提示用户输入中缀表达式,再利用程序将中缀表达式转换为后缀表达式,其中数字入队列,算术运算符入栈。
图3.2.1程序算法图
4
4.1
将中缀表达式转换为后缀表达式首先需要扫描中缀表达式,当遇到数字时,将其入队列,当遇到运算符时,若是低优先级则直接入栈,若是高优先级则将低优先级运算符弹出,并入队列,再将此次运算符入栈,最终形成后缀表达式
if (ch>='0' && ch<='9')
Push(S,ch-'0';)//数字字符到数值的转换
else{
y=Pop(S),x=Pop(S)
switch (ch){
case '+':Push(S,x+y);break;
case '-':Push(S,x-y);break;
case '*':Push(S,x*y);break;
case '/':Push(S,x/y);break;
}
}
5
5.1
输入一个中缀表达式:
5.2
输出后缀表达式及其结果:
6
6.1
在本次实验中,遇到的心得:
1为什么有判空队列不需要判空栈?因为当S->top=-1时栈变为空,不需要单独写一个函数出来判断。
2后缀表达式的求值中,Push(S,ch-'0')中的ch-‘0’是什么意思?因为输入表达式时数字是以字符的形式存储的,当进行计算式需要字符到数值的转换。
2.1
当我们需要进行一长串的计算时,各种运算符夹杂在一起,通过笔算很容易得出结果。然而计算机并没有人脑那么聪明,它并不懂得先乘除后加减,有括号要先计算括号里面的,它只知道从左到右的进行计算,这就造成了计算机计算的失误,科学的计算是人们非常需要的计算工具。
3
3.1
整个系统结构如图3-1-1所示,结构非常清楚,程序顺序执行,首先提示用户输入需要计算的表达式,经过转换得到后缀表达式,最后结果将数据显示到主屏幕上即可。
{
Q->front=0;
其伪代码如下:
x=Q->data[Q->front++];
4.2
由于在将中缀表达式转换为后缀表达式时已经将运算符安排在了合适的位置,在后缀表达式中不仅不需要括号,而且还完全免除了运算符优先规则,仅需从左到右计算即可。
其伪代码如下:
while(!QueueEmpty(Q)){
ch=DeQueue(Q)