一、实验目的
理解栈和队列的工作原理,掌握栈和队列在计算机程序设计中的应用。
二、实验内容
中缀表达式到后缀表达式的转换。
三、设计要求
以字符序列的形式从终端输入语法正确的、不含变量的整数表达式,利用给定的算符优先关系把中缀表达式转换成计算机容易处理的后缀表达式。本实验中操作数规定为1位数字字符,运算符只有+、-、*、/。
四、源程序
#include<stdio.h>
#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;
}
int 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");
}
中缀表达式转换为后缀表达式
int 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);
}