数据结构栈和队列的应用表达式的求值
2011-2012学年第一学期
数据结构课内实验报告
实验名:栈和队列的应用:表达式的求值
姓名:
学号:
班级:
指导老师:
日期:
实验题目:
1、实验目的:
通过此实验进一步理解栈和队列,提高运用理论解决实际问题的能力。2、实验内容:
例如,输入9-(2+4*7)/5+3# ,并按回车键,即可输出结果如下:
表达式的运算结果是:6
表达式的后缀表达式为:9 2 4 7 * +5/-3+
3、数据结构及算法思想:
表达式计算是实现程序设计逻辑语言的基本问题之一,也是栈和队列应用的一个典型的例子。该设计是先通过栈将中缀表达式转换为后缀表达式,在转换过程中又用到了队列的操作。而在得到后缀表达式之后,又用到队列的操作对生成的后缀表达式进行计算。在整个设计的实现过程中,用到的都是栈和队列的概念。
4、模块化分:
本程序分为2个模块:
(1)中缀表达式转换为后缀表达式;
(2)求后缀表达式
5、详细设计及运行结果:
(1)中缀表达式转换为后缀表达式
void CTPostExp(SeqQueue *Q){
SeqStack S; //运算符栈
char c,t;
InitStack(&S); //初始化栈
Push(&S,'#'); //压入栈底元素‘#’
do { //扫描中缀表达式
c=getchar();
switch(c){
case ' ':break; //去除空格符
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': EnQueue(Q,c);break;
case '(':Push(&S,c);break;
case ')':
case '#':
do{
t=Pop(&S);
if(t!='('&&t!='#') EnQueue(Q,t);
}while(t!='('&&S.top !=-1);break;
case '+':
case '-':
case '*':
case '/':
while(Priority(c)<=Priority(GetTop(S))){
t=Pop(&S);EnQueue(Q,t);
}
Push(&S,c);break;
}
}while(c!='#'); //以'#'号结束表达式扫描}
(2)后缀表达式的计算
DataType CPostExp(SeqQueue Q) {
SeqStack S;
char ch;
int x,y;
InitStack(&S);
while(!QueueEmpty(Q)){
ch=DeQueue(&Q);
if(ch>='0' &&ch<='9')
Push(&S,ch);
else{
y=Pop(&S)-'0';
x=Pop(&S)-'0';
switch(ch){
case '+':Push(&S,(char)(x+y+'0'));break;
case '-':Push(&S,(char)(x-y+'0'));break;
case '*':Push(&S,(char)(x*y+'0'));break;
case '/':Push(&S,(char)(x/y+'0'));break;
}
}
}
return GetTop(S);
}
输入9-(2+4*7)/5+3# ,并按回车键,
输出:表达式的运算结果是:6
表达式的后缀表达式为:9 2 4 7 * +5/-3
6、调试情况,设计技巧及体会:
表达式是由运算对象、运算符、括号组成的有意义的式子。要写此程序,必须了解到底什么是中缀表达式、后缀表达式并灵活运用栈和队列。
7、源程序清单:
#include
#define StackSize 100
#define QueueSize 100
/*队列的相关操作*/
typedef char DataType;
typedef struct{
char data[100];
int front,rear;
}SeqQueue; //定义队列类型
void InitQueue(SeqQueue *Q) { //初始化队列
Q->front =0;
Q->rear =0;
}
int QueueEmpty(SeqQueue Q) { //判空队列return Q.rear ==Q.front ;
}
void EnQueue(SeqQueue *Q,DataType x) { //入队列
if((Q->rear +1) % QueueSize==Q->front )
printf("Queue overflow");
else{
Q->data[Q->rear]=x;
Q->rear =(Q->rear +1)%QueueSize;
}
}
DataType DeQueue(SeqQueue *Q) {
char x;
if(QueueEmpty(*Q)) return 0;
else{
x=Q->data[Q->front ];
Q->front =(Q->front +1)%QueueSize;
return x;
}
} /*栈的相关操作*/
typedef struct{
DataType data[100];
int top;
}SeqStack; //栈类型的定义void InitStack(SeqStack *S) { //初始化栈
S->top =-1;
}
void Push(SeqStack *S,DataType x) { //入栈if(S->top ==StackSize-1)
printf("Stack ouerflow");
else{
S->top =S->top +1;
S->data [S->top ]=x;
}
}
DataType Pop(SeqStack *S) { //出栈
if(S->top ==-1) {
printf("stack underflow");
return 0;
}
else
return S->data[S->top --];
}
DataType GetTop(SeqStack S) {
//取栈顶元素
if(S.top ==-1) {
printf("stack empty");
return 0;
}
else
return S.data [S.top ];
} //求运算符优先级函数
int Priority(DataType op) {
switch(op){
case '(':
case '#':return 0;
case '-':
case '+':return 1;
case '*':
case '/':return 2;
}
return -1;
}
void CTPostExp(SeqQueue *Q){
SeqStack S; //运算符栈
char c,t;
InitStack(&S); //初始化栈
Push(&S,'#'); //压入栈底元素‘#’
do { //扫描中缀表达式
c=getchar();
switch(c){
case ' ':break; //去除空格符
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': EnQueue(Q,c);break; case '(':Push(&S,c);break;
case ')':
case '#':
do{
t=Pop(&S);
if(t!='('&&t!='#') EnQueue(Q,t);
}while(t!='('&&S.top !=-1);break;
case '+':
case '-':
case '*':
case '/':
while(Priority(c)<=Priority(GetTop(S))){
t=Pop(&S);EnQueue(Q,t);
}
Push(&S,c);break;
}
}while(c!='#'); //以'#'号结束表达式扫描
} //后缀表达式的计算
DataType CPostExp(SeqQueue Q){
SeqStack S;
char ch;
int x,y;
InitStack(&S);
while(!QueueEmpty(Q)){
ch=DeQueue(&Q);
if(ch>='0' &&ch<='9')
Push(&S,ch);
else{
y=Pop(&S)-'0';
x=Pop(&S)-'0';
switch(ch){
case '+':Push(&S,(char)(x+y+'0'));break;
case '-':Push(&S,(char)(x-y+'0'));break;
case '*':Push(&S,(char)(x*y+'0'));break;
case '/':Push(&S,(char)(x/y+'0'));break;
}
}
}
return GetTop(S);
}
void main(){
SeqQueue Q; //定义队列,存放后缀表达式
InitQueue(&Q); //初始化队列
CTPostExp(&Q); //调用转换函数将中缀表达式转换成后缀表达式
printf("表达式的运算结果是:%c\n",CPostExp(Q)); //输出计算结果printf("表达式的后缀表达式为:");
while(!QueueEmpty(Q)) //输出后缀表达式
printf("%2c",DeQueue(&Q));
printf("\n");
}