一、实验目的
1.掌握栈的存储表示和实现
2.掌握栈的基本操作实现。
3.掌握栈在解决实际问题中的应用。
二、实验要求
问题描述:设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。
(1)输入的形式:表达式,例如2*(3+4)#
包含的运算符只能有’+’ 、’-’ 、’’ 、’/’ 、’(’、 ‘)’,“#”代表输入结束符;
(2)输出的形式:运算结果,例如2(3+4)=14;
(3)程序所能达到的功能:对表达式求值并输出。
三、解题参考思路
为了实现用栈计算算数表达式的值,需设置两个工作栈:用于存储运算符的栈opter,以及用于存储操作数及中间结果的栈opnd。
算法基本思想如下:
(1)首先将操作数栈opnd设为空栈,而将’#‘作为运算符栈opter的栈底元素,这样的目的是判断表达式是否求值完毕。
(2)依次读入表达式的每个字,表达式须以’#‘结,读入字符若是操作数则入栈opnd,读入字符若是运算符,则将此运算符c与opter的栈顶元素top比较优先级后执行相应的操作,具体操作如下:
(i)若top的优先级小于c,即top<c,则将c直接入栈opter,并读入下一字符赋值给c;
(ii)若top的优先级等于c,即top=c,则弹出opter的栈顶元素,并读入下一字符赋值给c,这一步目的是进行括号操作;
(iii)若top优先级高于c,即top>c,则表明可以计算,此时弹出opnd的栈顶两个元素,并且弹出opter栈顶的的运算符,计算后将结果放入栈opnd中。直至opter的栈顶元素和当前读入的字符均为’#’,此时求值结束。
算符间的优先关系如下表所示(表来源:严蔚敏《数据结构》):
表中需要注意的是θ1为opter的栈顶元素,θ2为从表达式中读取的操作符,此优先级表可以用二维数组实现。
图例:
比较算符优先关系代码示例:
int getIndex(char theta) //获取theta所对应的索引
{
int index = 0;
switch (theta)
{
case ‘+’:
index = 0;
break;
case ‘-’:
index = 1;
break;
case ‘*’:
index = 2;
break;
case ‘/’:
index = 3;
break;
case ‘(’:
index = 4;
break;
case ‘)’:
index = 5;
break;
case ‘#’:
index = 6;
default:break;
}
return index;
}
char getPriority(char theta1, char theta2) //获取theta1与theta2之间的优先级
{
const char priority[][7] = //算符间的优先级关系
{
{ ‘>’,’>’,’<’,’<’,’<’,’>’,’>’ },
{ ‘>’,’>’,’<’,’<’,’<’,’>’,’>’ },
{ ‘>’,’>’,’>’,’>’,’<’,’>’,’>’ },
{ ‘>’,’>’,’>’,’>’,’<’,’>’,’>’ },
{ ‘<’,’<’,’<’,’<’,’<’,’=’,‘0’ },
{ ‘>’,’>’,’>’,’>’,‘0’,’>’,’>’ },
{ ‘<’,’<’,’<’,’<’,’<’,‘0’,’=’ },
};
int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
四、实验任务
认真阅读与理解实验内容的具体要求,参考教材相关章节,结合实验内容的要求,编写实验程序并上机调试与测试,完成实验报告的撰写。
(已改)代码如下
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 100 // 存储空间初始分配量
typedef int Status;
typedef struct
{
int data[MAXSIZE];
int top; // 用于栈顶指针
}opndStack;
typedef struct
{
char data[MAXSIZE];
int top; // 用于栈顶指针
}opterStack;
//====================================================================
int getIndex(char theta) //获取theta所对应的索引
{
int index = 0;
switch (theta)
{
case '+':
index = 0;
break;
case '-':
index = 1;
break;
case '*':
index = 2;
break;
case '/':
index = 3;
break;
case '(':
index = 4;
break;
case ')':
index = 5;
break;
case '#':
index = 6;
default:break;
}
return index;
}
//====================================================================
char getPriority(char theta1, char theta2) //获取theta1与theta2之间的优先级
{
const char priority[][7] = //算符间的优先级关系
{
{
'>','>','<','<','<','>','>' },
{
'>','>','<','<','<','>','>' },
{
'>','>','>','>','<','>','>' },
{
'>','>','>','>','<','>','>' },
{
'<','<','<','<','<','=','0' },
{
'>','>','>','>','0','>','>' },
{
'<','<','<','<','<','0','=' },
};
int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
//====================================================================
Status InitopndStack(opndStack *S)//建立opnd空栈
{
S->top=-1;
return OK;
}
Status InitopterStack(opterStack *S)//建立opter空栈
{
S->top=-1;
return OK;
}
//====================================================================
Status Pushnd(opndStack *S,int n)//入栈
{
if(S->top== MAXSIZE-1)
{
return ERROR;
}
S->top++;//
S->data[S->top]=n;
return OK;
}
Status Pushter(opterStack *S,char n)
{
if(S->top== MAXSIZE-1)
{
return ERROR;
}
S->top++;//
S->data[S->top]=n;
return OK;
}
//=========================================================
Status Popnd(opndStack *S,int *n)//出栈 并返回到 n 中
{
if(S->top==-1)
return ERROR;
*n=S->data[S->top];
(S->top)--;
return OK;
}
Status Popter(opterStack *S,char *n)
{
if(S->top==-1)
return ERROR;
*n=S->data[S->top];
S->top--;
return OK;
}
//=======================================================
signed int calculate(int x1,int x2,char c)
{
switch(c)
{
case '+':
return (x1+x2);
case '-':
return (x1-x2);
case '*':
return (x1)*(x2);
case '/':
return (x1)/(x2);
default:
return 0;
}
return 0;
}
//======================================================
int isdigit(char c)//判断是否为操作数
{
if(c<='9'&& c>='0')
return 1;
else
return 0;
}
int ischar(char c)//判断是否为运算符
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '#':
return 1;
default:
return 0;
}
return 0;
}
//=========================================================
void input(char s[]) //输入表达式 存入s[]数组中。
{
char c;
int i = 0;
while(c!='#')
{
while((c=getchar())==' ');//跳过所有空格进行c的输入
s[i++]=c;
}
return ;
}
//==========================================================
int calculateall()
{
char c,s[100]={
0},k;
int x1,x2,i=0;
int n=0;
opndStack opnd;
opterStack opter;
InitopndStack(&opnd); //空栈
InitopterStack(&opter);
Pushter(&opter,'#');
input(s);
while(s[i]!='\0')
{
c=s[i];
if(ischar(c))
{
switch(getPriority(opter.data[opter.top],c))
{
case '<':
Pushter(&opter,c);
break;
case '=':
Popter(&opter,&k);//k没有用处 用来满足函数关系而已
break;
case '>':
while(getPriority(opter.data[opter.top],c)=='>')
{
Popnd(&opnd,&x1);
Popnd(&opnd,&x2);
Popter(&opter,&k);
x1=calculate(x2,x1,k);
Pushnd(&opnd,x1);
}
if(getPriority(opter.data[opter.top],c)=='<')
Pushter(&opter,c);
else
Popter(&opter,&k);
break;
default:
printf("INPUT ERROR");
}
}
else
{
Pushnd(&opnd,c-'0');
}
++i;
}
Popnd(&opnd,&k);
return k;
}
//=========================================================
int main()
{
int k;
k=calculateall();
printf("%d",k);
return 0;
}
当时自己写的版本(c++)
#include <iostream>
using namespace std;
#include <string>
#define size2 10
#define size1 100
#define erro -1
typedef int iii;
typedef struct
{
char *base;
char *top;
int size;
} stack2;
typedef struct
{
iii * base;
iii* top;
int size;
} stack;
void InitStack(stack2 &s)//初始化栈
{
s.base=(char*)malloc (size1*sizeof(char));
if(!s.base)
{
printf("超出界限\n");
return;
}
else
{
s.top=s.base;
s.size=size1;
}
}
void InitStack(stack &s)//初始化栈
{
s.base=(iii *)malloc (size1*sizeof(iii));
if(!s.base)
{
printf("超出界限\n");
return;
}
else
{
s.top=s.base;
s.size=size1;
}
}
void Insert(stack2 &s,char a) //插入元素
{
if(s.top-s.base>=s.size)
{
s.base=(char *)realloc (s.base,(s.size+size1)*sizeof (char));
if(!s.base)
{
printf("超出界限\n");
return ;
}
}
*s.top++=a;
}
void Insert2( stack &s,int a)
{
if(s.top-s.base>=s.size)
{
s.base=(iii *)realloc (s.base,(s.size+size1)*sizeof (iii));
if(!s.base)
{
printf("超出界限\n");
return ;
}
}
*s.top++=a;
}
char Pop(stack2 &s )//删除栈顶元素,并返回栈顶元素
{
if(s.top==s.base)
{
printf("栈为空\n");
return erro;
}
else
{
*--s.top;
return * s.top;
}
}
int Pop2(stack &s)
{
if(s.top==s.base)
{
printf("栈为空\n");
return erro;//没意义
}
else
{
*--s.top;
return * s.top;
}
}
void View(stack &s)
{
for(int i=1; i<=(s.top-s.base); i++)
{
char k;
k=*(s.top-i);
cout<<k<<endl;
}
}
char GetPop(stack2 &s)
{
if(s.top==s.base)
{
printf("栈为空\n");
return-1;
}
else
return *(s.top-1);
}
int GetPop2(stack &s)
{
if(s.top==s.base)
{
printf("栈为空\n");
return-1;
}
else
return *(s.top-1);
}
char Compare(char q,char r)//比较优先级
{
int j[2];
char str[2];
char table[7][7]=
{
{
'>','>','<','<','<','>','>'},
{
'>','>','<','<','<','>','>'},
{
'>','>','>','>','<','>','>'},
{
'>','>','>','>','<','>','>'},
{
'<','<','<','<','<','=','e'},
{
'>','>','>','>','e','>','>'},
{
'<','<','<','<','<','e','='}
};
str[0]=q;
str[1]=r;
for(int i=0; i<2; i++)
{
switch(str[i])
{
case '+':
j[i]=0;
break;
case '-':
j[i]=1;
break;
case '*':
j[i]=2;
break;
case '/':
j[i]=3;
break;
case '(':
j[i]=4;
break;
case ')':
j[i]=5;
break;
case '#':
j[i]=6;
break;
}
}
return table[j[0]][j[1]];
}
int Operate (int a,char b,int c)
{
switch(b)
{
case '+':
return a+c;
case '-':
return a-c;
case '*':
return a*c;
case '/':
return a/c;
}
}
bool Decide(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')
return true;
else
return false;
}
int main()
{
stack2 a;
stack b;//a存储符号,b存储数字
InitStack(a);
Insert(a,'#');
InitStack(b);
char c;
c=getchar();
int temp=0;
while (c!='#'||GetPop(a)!='#')
{
if(!Decide(c))
{
temp=(temp*10+c-'0');//可支持数位数字
c=getchar();
}
else if(Decide(c))
{
if(temp!=0)
{
Insert2(b,temp);
}
temp=0;
switch(Compare(GetPop(a),c))
{
case '<':
//栈顶元素优先权低
//cout<<"<"<<endl;
Insert(a,c);
c=getchar();
break;
case '=':
//脱括号
Pop(a);
c=getchar();
break;
case'>':
char f=Pop(a);
int g=Pop2(b);
int h=Pop2(b);
Insert2(b,Operate(h,f,g));
break;
}
}
}
cout<<"结果为"<<endl;
cout<<GetPop2(b)<<endl;
return 0;
}