数据结构实验项目二 栈的基本操作及其应用

 

课程名称:数据结构

实验目的

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;
}

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值