栈实现个位数四则运算

蓝咒 提交于 2020-01-29 07:05:50

写一个程序,使得该程序能够完成个位数的四则运算,但要用到栈的基本操作。既然是实验就会有它的目的和要求。
实验目的:1.掌握栈的定义及实现方法;
2.掌握利用栈求解算术表达式的方法。
实验要求:1.使用链式存储结构完成栈的各种基本操作;
2.补充完成In©, Preced(t1,t2), Operate(a,theta,b)三个函数。
栈是一种先进后出的线性表,既然是线性表,就可以有顺序形式,即顺序栈;也可以有链式形式,即链栈。本实验是要求用链式存储结构,所以以下内容就是关于链栈的表示和实现,以及用链栈实现个位数的四则运算。
初始化:即构造一个空栈,因为没必要设置头结点,所以直接将栈顶指针置空即可。
【算法描述】

Status InitStack(LinkStack &S)
{
	S=NULL;
	return OK;
}

入栈:链栈在入栈前不需要判断栈是否满,然而顺序栈的入栈操作是要判断的,链栈只需要为入栈元素动态分配一个结点空间。
【算法描述】

Status Push(LinkStack &S,SElemType e)
{
	p=new StackNode;
	p->data=e;
	p->next=S;  //将新结点插入栈顶
	S=p;     //修改栈顶指针为p
	return OK;
}

出栈:出栈前需要判空,跟顺序栈时一样的,但是,链栈跟链表的删除一样,出栈后需要释放栈顶元素的栈顶空间。
【算法描述】

Status Pop(LinkStack &S,SElemType e)
{
	if(S==NULL) return ERROR;  //栈为空的情况
	e=S->data;
	p=S;  //临时保存,以备释放;
	S=S->next;  //修改栈顶指针
	delete p;  //释放原栈顶元素空间
	return OK;
}

取栈顶元素:与顺序栈一样,当栈非空时,此操作返回当前栈顶元素的值,栈顶指针S保持不变。
【算法描述】

SElemType GetTop(LinkStack S)
{
	if(S!=NULL)
		return S->data;
}

链栈的基本操作就是以上这些,根据上面的基本操作以及要补充的代码(这些代码在后面的程序中有,里面的代码也简单,应该能看得懂),实现实验要求的完整代码如下:
【完整代码】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OVERFLOW -1 
#define OK 1
#define ERROR 0

typedef int Status;
typedef char SElemType;

typedef struct StackNode 
{
    SElemType  date;     
    struct StackNode *next;         
}StackNode,*LinkStack; 


Status InitStack (LinkStack &S)
{
    S=NULL;    
    return OK;
}

Status Push(LinkStack &S,SElemType e) 
{
    LinkStack p;
	p=new StackNode;
	p->date=e;
	p->next=S;
	S=p;  
    return OK; 
}

Status Pop(LinkStack &S,SElemType &e)
{ 
	LinkStack p;
    if(S==NULL)  return ERROR;
	e=S->date;
	p=S;
	S=S->next;
	delete p;
    return OK;
    
} 

SElemType GetTop(LinkStack S) 
{   
    if(S!=NULL)
    	return S->date;
}

Status In(char ch)
{
	switch(ch)	//判断c是否为运算符
	{
	case '+':
		return OK;
	case '-':
		return OK;
	case '*':
		return OK;
	case '/':
		return OK;
	case '(':
		return OK;
	case ')':	
		return OK;
	case '#':
		return OVERFLOW;
	default:
		return ERROR;
	}
}

//比较运算符的优先级 
SElemType Precede(SElemType a,SElemType b)
{
	if(b=='+')
	{
		if(a=='('||a=='#')
			return '<';
		return '>';
	}
	if(b=='-')
	{
		if(a=='('||a=='#')
			return '<';
		return '>';
	}
	if(b=='*')
	{
		if(a=='*'||a==')'||a=='/')
			return '>';
		return '<';
	}
	if(b=='/')
	{
		if(a=='*'||a==')'||a=='/')
			return '>';
		return '<';
	}
	if(b=='(')
		return '<';
	if(b==')')
	{
		if(a=='(')
			return '=';
		return '>';
	}
	if(b=='#')
	{
		if(a=='#')
			return '=';
		return '>';
	}
}

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 OPTR,OPND; 
	char ch,theta,a,b,x;
	InitStack(OPND);		//初始化运算符栈
	InitStack(OPTR);		//初始化操作数栈
	Push(OPTR,'#');
	scanf("%c",&ch);
	while(ch!='#'||GetTop(OPTR)!='#')
	{
		if(!In(ch))
		{
			Push(OPND,ch);
			scanf("%c",&ch);	//ch不是运算符则进OPND栈
		}
		else
			switch(Precede(GetTop(OPTR),ch))		//比较OPTR的栈顶元素跟ch的优先级
		{
			case '<':
				Push(OPTR,ch);
				scanf("%c",&ch);	//读取下一字符ch
				break;
			case '>':
				Pop(OPTR,theta);
				Pop(OPND,b);
				Pop(OPND,a);
				Push(OPND,Operate(a,theta,b));
				break;
			case '=':
				Pop(OPTR,x);
				scanf("%c",&ch);
				break;
		}		//switch
	}		//while
	return GetTop(OPND);	//OPND 栈顶元素即为表达式的求值结果
}

int main()
{
	char w;
	printf("请输入算术表达式,并以#号结束。\n");
	w=EvaluateExpression();    //将运算结果赋值给w 
    w=w-48;         //将字符转换成数字 
	printf("the result of expression is: %d\n",w);
	printf("\n\n请按任意键退出!");
	return 0;
} 

程序运行及试验结果:
在这里插入图片描述
注意:此处我输入的括弧只能是英文的。
看不懂的可以在下方留言,如果我看到,可以给你们解答。

【参考文献】:《数据结构》(C语言版|第2版)严蔚敏 李冬梅 吴伟民编著

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!