课程名称:数据结构
实验目的:
1.掌握栈的定义及实现;
2.掌握利用栈求解算术表达式的方法。
实验要求:
1、 使用链式存储结构完成栈的各种基本操作;
2、 补充完成In(c), Preced(t1,t2),Operate(a,theta,b)三个函数。
实验题目:栈的基本操作及其应用
实验过程:
1、通过修改完善教材中的算法3.22,利用栈来实现算术表达式求值的算法。对算法3.22中调用的几个函数要给出其实现过程:
(1) 函数In(c):判断c是否为运算符;
(2) 函数Precede(t1,t2):判断运算符t1和t2的优先级;
(3) 函数Operate(a,theta,b):对a和b进行二元运算theta。
2、程序运行时,输入合法的算术表达式(中间值及最终结果要在0~9之间,可以包括加减乘除和括号),便可输出相应的计算结果。
实验提示:(仅供参考,每个函数的具体实现可以有多种方法,希望有创新)
1. 将栈的定义和实现单独保存在头文件“stack.h”中,然后在表达式求值的源程序中包含此头文件(即#include“stack.h”)。
2.表达式求值源程序的具体实现
(1) 主函数如下:
void main()
{
Printf(“请输入算术表达式,并以#结束.\n”);
Printf(“the result of expression is:%d\n”,EvaluateExpression());
}
(2) 函数EvaluateExpression的实现见算法3.22
(3) 函数In(c)的实现可以采用以下方式:
Status In(SElemType c)// 应在前面有定义typedef char SElemType;
{ // 判断c是否为运算符
switch(c)
{
case'+':return TRUE;
……//补充完整
default:return FALSE;
}
}
(4) 函数Precede(t1,t2)的实现可以采用以下形式:
SElemType Precede(SElemType t1,SElemType t2)
{ //根据教材表3.1,判断两个运算符的优先关系
SElemType f;
switch(t2)
{
case '+':
case '-':if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
……//补充完整
}
return f;
}
(5) 函数Operate(a,theta,b)的实现可以采用以下方式:
SElemType Operate(SElemType a,SElemType theta,SElemType b)
{
SElemType c;
a=a-48;
b=b-48;
switch(theta)
{
case'+':c=a+b+48;
break;
……//补充完整
}
return c;
}
选做内容:进一步改进,使表达式的中间值及最终结果不局限于0~9之间的个位数。(如果完成要在实验报告中注明),如下图:
实验结果:
输入:2*(4-1)+8
输出:14
该程序能够完成个位数的四则运算。
实验分析:
1.栈的操作的特点;
2.列举调试运行过程中出现的错误并分析原因。
要求:
(1) 程序要添加适当的注释,程序的书写要采用缩进格式。
(2) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 上传源程序到课堂派,源程序保存为calculator.cpp。
#include<stdio.h> //运算过程不可出现一位以上数字
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char ElemType;
typedef char SElemType;
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
Status InitStack(LinkStack &S)
{
S=NULL;
return OK;
}
Status Push(LinkStack &S,SElemType e)
{
LinkStack p=new StackNode;
p->data=e;
p->next=S;
S=p;
return OK;
}
ElemType GetTop(LinkStack S)
{
if(S!=NULL)
return S->data;
}
Status Pop(LinkStack &S,SElemType &e)
{
if(S==NULL) return ERROR;
e=S->data;
LinkStack p=S;
S=S->next;
delete p;
return OK;
}
Status In(SElemType c)
{
switch(c)
{
case'+':return TRUE;
case'-':return TRUE;
case'*':return TRUE;
case'/':return TRUE;
case'(':return TRUE;
case')':return TRUE;
case'#':return TRUE;
default:return FALSE;
}
}
SElemType Precede(SElemType t1,SElemType t2)
{
SElemType f;
switch(t2)
{
case '+':
if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '-':
if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '*':
if(t1=='+'||t1=='-'||t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '/':
if(t1=='+'||t1=='-'||t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '(':
f='<';
break;
case ')':
if(t1=='(')
f='=';
else
f='>';
break;
case '#':
if(t1=='#')
f='=';
else
f='>';
break;
}
return f;
}
SElemType Operate(SElemType a,SElemType theta,SElemType b)
{
SElemType c;
a=a-'0';
b=b-'0';
switch(theta)
{
case'+':
c=a+b+'0';
break;
case'-':
c=a-b+'0';
break;
case'*':
c=a*b+'0';
break;
case'/':
c=a/b+'0';
break;
}
return c;
}
char EvaluateExpression()
{
LinkStack OPND;//装数字
LinkStack OPTR;//装运算符
InitStack(OPND);//初始化
InitStack(OPTR);
Push(OPTR,'#');//将表达式起始符起始符"#"压入OPTR栈
char ch;
cin>>ch;
while(ch!='#'||GetTop(OPTR)!='#')
{
if(!In(ch))
{
Push(OPND,ch);
cin>>ch;
}
else
switch(Precede(GetTop(OPTR),ch))
{
case '<':
Push(OPTR,ch);
cin>>ch;
break;
case '>':
SElemType theta;
SElemType b;
SElemType a;
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
case '=':
SElemType x;
Pop(OPTR,x);
cin>>ch;
break;
}
}
return GetTop(OPND);
}
int main()
{
printf("请输入算术表达式,并以#结束.\n");
printf("The result of expression is:%c\n",EvaluateExpression());
}
#include<iostream> //可进行多位数运算
#include<string.h>
#include<string>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef string ElemType;
typedef string SElemType;
typedef struct StackNode
{
ElemType data;
struct StackNode* next;
}StackNode, * LinkStack;
Status InitStack(LinkStack& S)
{
S = NULL;
return OK;
}
Status Push(LinkStack& S, SElemType e)
{
LinkStack p = new StackNode;
p->data = e;
p->next = S;
S = p;
return OK;
}
ElemType GetTop(LinkStack S)
{
if (S != NULL)
return S->data;
}
Status Pop(LinkStack& S, SElemType& e)
{
if (S == NULL) return ERROR;
e = S->data;
LinkStack p = S;
S = S->next;
delete p;
return OK;
}
Status In(ElemType c)
{
char C = c[0];
switch (C)
{
case'+':return TRUE;
case'-':return TRUE;
case'*':return TRUE;
case'/':return TRUE;
case'(':return TRUE;
case')':return TRUE;
case'#':return TRUE;
default:return FALSE;
}
}
SElemType Precede(SElemType T1, SElemType T2)
{
SElemType f;
char t1 = T1[0];
char t2 = T2[0];
switch (t2)
{
case '+':
if (t1 == '(' || t1 == '#')
f = "<";
else
f = ">";
break;
case '-':
if (t1 == '(' || t1 == '#')
f = "<";
else
f = ">";
break;
case '*':
if (t1 == '+' || t1 == '-' || t1 == '(' || t1 == '#')
f = "<";
else
f = ">";
break;
case '/':
if (t1 == '+' || t1 == '-' || t1 == '(' || t1 == '#')
f = "<";
else
f = ">";
break;
case '(':
f = "<";
break;
case ')':
if (t1 == '(')
f = "=";
else
f = ">";
break;
case '#':
if (t1 == '#')
f = "=";
else
f = ">";
break;
}
return f;
}
int string_to_int(SElemType a)
{
int n = 0;
for (int i = 0; i < a.size(); i++)
{
n = n * 10 + a[i] - '0';
}
return n;
}
SElemType Operate(SElemType a, SElemType Theta, SElemType b)
{
SElemType c;
int C;
int A = string_to_int(a);
int B = string_to_int(b);
char theta = Theta[0];
switch (theta)
{
case'+':
C = A + B;
break;
case'-':
C = A - B;
break;
case'*':
C = A * B;
break;
case'/':
C = A / B;
break;
}
c = to_string(C);
return c;
}
void judge(SElemType& S, ElemType& E, int& i)
{
int n = 0;
if (S[i] >= '0' && S[i] <= '9')
{
while (S[i] >= '0' && S[i] <= '9')
{
n = n * 10 + S[i] - '0';
i++;
}
E = to_string(n);
}
else
{
E = S[i];
i++;
}
}
ElemType EvaluateExpression()
{
LinkStack OPND;//装数字
LinkStack OPTR;//装运算符
InitStack(OPND);//初始化
InitStack(OPTR);
Push(OPTR, "#");//将表达式起始符起始符"#"压入OPTR栈
SElemType S;
cin >> S;
ElemType E;
int i = 0;
judge(S, E, i);
// cout << "E: " << E << endl;
while (E != "#" || GetTop(OPTR) != "#")
{
if (!In(E))
{
Push(OPND, E);
judge(S, E, i);
}
else
{
ElemType temp;
char ch;
temp = Precede(GetTop(OPTR), E);
ch = temp[0];
switch (ch)
{
case'<':
Push(OPTR, E);
judge(S, E, i);
break;
case'>':
{
SElemType theta;
SElemType b;
SElemType a;
Pop(OPTR, theta);
Pop(OPND, b);
Pop(OPND, a);
Push(OPND, Operate(a, theta, b));
break;
}
case'=':
{
SElemType x;
Pop(OPTR, x);
judge(S, E, i);
break;
}
}
}
}
return GetTop(OPND);
}
int main()
{
printf("请输入算术表达式,并以#结束.\n");
printf("The result of expression is: ");
ElemType ans = EvaluateExpression();
cout << ans;
}