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

实验项目二:栈的基本操作及其应用

展示

实验目的:

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 
#include 
#include 
#include 
 
using namespace std; 
#define MAXSIZE  100				//顺序栈存储空间的初始分配量 
#define OK 1
#define ERROR 0
 
typedef int Status;
typedef char ElemType; 
	
//链栈的存储结构
typedef struct StackNode
{
	ElemType data;
	struct StackNode *next;
 }StackNode,*LinkStack;
 
//链栈初始化 
Status InitStack(LinkStack &S)
{
	S=NULL;
	return OK;
 }
 
//入栈操作
Status Push(LinkStack &S,char e)
{
	LinkStack p;
	p=new StackNode;
	p->data=e;
	p->next=S;
	S=p;
	return OK;
 } 
 
//链栈的出栈
Status Pop(LinkStack &S,char &e)
{
	LinkStack p;
	if(S==NULL) return ERROR;
	e=S->data;
	p=S;
	S=S->next;
	delete p;
	return OK;
 } 
 
//取栈顶元素
char GetTop(LinkStack S)
{
	if(S!=NULL) 
		return S->data;
 } 
 
//判断是否是运算符 
bool In(char c)
{
	if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#') return 1;
	else return 0;
}
 
//比较OPTR栈顶元素和ch的优先级(运算符的优先级)
char Precede(char t1,char t2)
{
	char f;
	if(t1=='+'||t1=='-')
	{
		if(t2=='*'||t2=='/'||t2=='(') f='<';
		else f='>';
	 } 
	else if(t1=='*'||t1=='/')
	{
		if(t2=='(') f='<';
		else f='>';
	}
	else if(t1=='(') 
	{
		if(t2==')') f='=';
		else f='<';
	}
	else if(t1==')')
	{
		f='>';
	}
	else if(t1=='#')
	{
		if(t2=='=') f='=';
		else f='<';
	}
 	
	return f;
 } 
 
//计算简单算术式
char Operate(char a,char theta,char b)
{
	char ans;
	if(theta=='+') ans=(a-'0')+(b-'0')+'0';
	else if(theta=='-') ans=(a-'0')-(b-'0')+'0';
	else if(theta=='*') ans=(a-'0')*(b-'0')+'0';
	else if(theta=='/') ans=(a-'0')/(b-'0')+'0';
	
	return ans;
 } 
 
//构建函数,求解算数表达式 
char EvaluateExpression()
{
	printf("请输入一个表达式:\n"); 
	StackNode *OPND;//定义运算数栈
	StackNode *OPTR;//定义运算符栈 
	InitStack(OPND);				//初始化OPND栈,压入操作数和运算结果
	InitStack(OPTR);				//初始化OPTR栈,压入操作符
	char c;//起始输入# 
	cin>>c;
	Push(OPTR,c);					//将表达式起始符'#'压入OPTR栈顶
	char ch;
	cin>>ch;
	while(ch!='#'||GetTop(OPTR)!='#') 			//用ch!='#'来判断表达式是否扫描完毕,表达式		
	{										    //没有扫描完毕或OPTR栈顶元素不为'#'则继续执行
		if(!In(ch))	
		{
			Push(OPND,ch);
			cin>>ch; 
		}			
		else 
		
			switch(Precede(GetTop(OPTR),ch))
			{
				case '<':
					
						Push(OPTR,ch);cin>>ch;
						break;
					
				case '>':
					
						char theta;
						char a,b;
						Pop(OPTR,theta);
						Pop(OPND,b);
						Pop(OPND,a);
						Push(OPND,Operate(a,theta,b));
						break;
					
				case '=':
					
					char x;
					Pop(OPTR,x);
					cin>>ch;
					break;
							
			}					
	}
	return GetTop(OPND);										
} 													
 
int main()
{
 	char res=EvaluateExpression();
 	printf("结果为:");
	cout<

终于完成这个程序了啊,心里很高兴。过程一如既往的困难,因为自己的不细心和小失误,但还好坚持写完了。

书上代码还是不能全信啊,要独立思考。 

有两个印象深刻的收获:

1、如何查bug?

第一遍我在查bug的时候照着书本一个字母一个字母的查,这办法挺傻的。

后来我就改变策略了。

如果程序出错了,(1)你可以把分函数一个一个执行,从而精确寻找错误,(2)在程序语句中插入如printf等,通过运行结果查找错误,(3)和别人正确的代码对比,把别人的分函数复制过来使用,精确寻找错误。

2、之前只注意到写程序的时候不能使用中文符号,没想到这次在输入中使用了中文符号致错,花了好长时间才找出来。

你可能感兴趣的:(C语言数据结构)