第三章-栈(2)举例应用

表达式求值:
表达式求值:

先建立一个文件: 文件名为  stack.cpp

//头文件  
#include"stdio.h" 
#include"stdlib.h"
#include"malloc.h"  
  
//宏定义  
#define STACK_INIT_SIZE 100     //存储空间初始分配量  
#define STACKINCREMENT 10         //存储空间分配增量  
#define TRUE 1
#define FALSE 0  
#define OK 1  
#define ERROR 0  
#define INFEASIBLE -1  
#define OVERFLOW -2  
  
typedef char SElemType;  
typedef char Status;  
  
//栈的顺序结构体  
typedef struct{  
    SElemType *base;              //在栈构造之前和销毁之后,base 的值为NULL;  
    SElemType *top;               //栈顶指针  
    int stacksize;                //当前已分配的存储空间,以元素为单位  
}SqStack;  
  
//------------基本操作的函数原型说明--------------  
//Status InitStack(SqStack &S);      //构造一个空栈S  
  
//Status DestroyStack(SqStack &S);   //销毁栈S,S不再存在  
  
//Status ClearStack(SqStack &s);     //把栈S置位空  
  
//Status StackEmpty(SqStack S);    //若栈S为空栈,则返回TRUE,否则返回FALSE  
  
//int StackLength(SqStack S);      //返回S的元素个数,即栈的长度  
  
//Status GetTop(SqStack S,SElemType &e);     //若栈不为空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR  
  
//Status Push(SqStack &S,SElemType e);        //插入元素e为新的栈顶元素  
  
//Status Pop(SqStack &S,SElemType &e);        //若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR  
  
//Status StackTraverse(SqStack S,Status (*visit) () );        
        //从栈底到栈顶依次对栈中每个元素调用函数 visit() , 一旦 visit() 失败,则操作失败  
  
//1.构建栈  
Status InitStack(SqStack &S){  
    //构造一个空栈S  
    S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));  
    if(! S.base) exit(OVERFLOW);  //存储分配失败  
    S.top=S.base;    //当栈为空时,栈底等于栈顶  
    S.stacksize=STACK_INIT_SIZE;    //栈可存储的个数  
    return OK;  
}  
  
//2.销毁栈  
Status DestroyStack(SqStack &S){  
    S.top=NULL;  
    S.stacksize=0;  
    free(S.base);  
    return OK;  
}  
  
//3.清空栈  
Status ClearStack(SqStack &S){  
    S.top=S.base;   //栈顶和栈底指向同一个位置,即为空  
    return OK;  
}  
  
//4.判断栈是否为空  
Status StackEmpty( SqStack S)  
{  
    if(S.top==S.base)  
        return ERROR;  
    else  
        return TRUE;  
}  
  
//5.求栈的长度  
Status StackLength(SqStack S)  
{  
    int n;  
    if(S.top==S.base)  
        return FALSE;  
    else{  
        n=S.top-S.base;  
        return n;  
    }  
}  
  
//6.求栈顶元素  
Status GetTop(SqStack S,SElemType &e)  
{  
    if(S.top==S.base)  
        return FALSE;  
    else  
        return ( e=*(S.top-1) );  
}  
  
//7.栈顶插入元素  
Status Push(SqStack &S,SElemType &e)  
{       //插入元素 e 为新的栈顶元素  
    if(S.top-S.base >= STACK_INIT_SIZE)  //栈满的时候就需要追加存储空间  
    {  
        S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));   
        if(!S.base)  exit(OVERFLOW);    //存储空间分配失败  
  
        S.top=S.base+S.stacksize;   //栈底的位置可能改变,需要重新定位栈顶元素  
        //S.top 还是之前的那个没有存储的位置     
  
        S.stacksize = S.stacksize+STACKINCREMENT;  
    }  
    *S.top=e;  
    S.top++;  
    return OK;  
}  
  
  
//8.栈顶出栈元素  
Status Pop(SqStack &S,SElemType &e){  
    //若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK ,否则返回ERROR  
    if(S.top == S.base)  return ERROR;  
    e=*(--S.top);     //可以不加括号,但需要记住的是,需要让 top 指针减 1 ,再取出元素  
    return OK;  
}  
  
//9.遍历栈   
Status StackTraverse(SqStack S){  
    if(S.base==NULL)  return ERROR;  
    if(S.top==S.base){  
        printf("栈为空,没有元素-------!");  
        return FALSE;  
    }  
    SElemType *p=S.top;   //先找出 top 的地址  
    while(p > S.base)  
    {  
        p--;  
        printf("%d\n",*p);  
    }  
    return OK;  
}  

再建一个文档,文件名为    expression.cpp

#include<stdio.h>
#include"Stack.cpp"    //Stack.cpp 中包含了各种对栈的操作,直接调用就可以了

Status In(SElemType c){  //判断c是否为运算符
	switch(c){
	case '+':
		return 1; break;
	case '-':
		return 1; break;
	case '*':
		return 1; break;
	case '/':
		return 1; break;
	case '(':
		return 1; break;
	case ')':
		return 1; break;
	case '#':
		return 1; break;
	default: 
		return 0;
	}
}


//比较两个运算符的优先级
//a,b中存放待比较的运算符
// a>b  是a的运算符 大于 b 的运算符
// 0 表示不能出现
Status Precede(SElemType a,SElemType b){
	int i,j;
	char table[7][7]={         //运算符的表格
         //  +   -   *   /   (   )   #
 /* + */   {'>','>','<','<','<','>','>'}, 
 /* - */   {'>','>','<','<','<','>','>'},
 /* * */   {'>','>','>','>','<','>','>'},
 /* / */   {'>','>','>','>','<','>','>'},  
 /* ( */   {'<','<','<','<','<','=','0'},
 /* ) */   {'>','>','>','>','0','>','>'},
 /* # */   {'<','<','<','<','<','0','='}
	};
	switch(a){  
        case '+': i=0; break;  
        case '-': i=1; break;  
        case '*': i=2; break;  
        case '/': i=3; break;  
        case '(': i=4; break;  
        case ')': i=5; break;  
        case '#': i=6; break;  
    }  
    switch(b){  
        case '+': j=0; break;  
        case '-': j=1; break;  
        case '*': j=2; break;  
        case '/': j=3; break;  
        case '(': j=4; break;  
        case ')': j=5; break;  
        case '#': j=6; break;  
    }  
    return table[i][j];  
}

SElemType Operate(SElemType a,SElemType theta,SElemType b){  //计算a,b运算后的数值
	int i,j,result;
	i=a;  
    j=b;  
  
    switch(theta)   {  
        case '+': result = i + j; break;  
        case '-': result = i - j; break;  
        case '*': result = i * j; break;  
        case '/': result = i / j; break;  
    }  
    return result; 
}

SElemType EvaluateExpression(){
	//算术表达式求值得算符优先算法,设OPTR(运算符栈) 和OPND(运算数栈)分别为 运算符栈 和 运算数栈
	//OP 为运算符集合
	SElemType c;           //getchar 输入的
	SElemType e;           //获得的栈顶元素
	SElemType theta;       //从栈中弹出的元素
	SElemType a,b;         //从OPND中出栈的数字
	SElemType result;      //进行 Operate 操作后的结果
	SElemType x;
	SqStack OPTR,OPND;   
	InitStack(OPTR);    c='#';  Push(OPTR,c);
	InitStack(OPND);     
	
	c=getchar();
	GetTop(OPTR,e);     //获取栈顶元素
	while( c!='#' || e!='#' ){
		//如果不运算符,就入OPND栈, 接着获取下一个数字
		if(! In(c) ){  Push(OPND,c);   c=getchar();   GetTop(OPTR,e); }
		else{
			switch( Precede(e,c) ){       //将刚栈顶的元素与刚输入的元素进行比较
			case '<':     //栈顶元素的优先权低
				Push(OPTR,c);        //压入栈 , 读取下一个字符
				c=getchar();
				GetTop(OPTR,e);
				break;

			case '>':     //栈顶元素的优先权高
				Pop(OPTR,theta);        //退栈并将运算结果入栈  
                Pop(OPND,b);
				Pop(OPND,a);   

				result=Operate(a,theta,b);
                Push(OPND,result);
				GetTop(OPTR,e);
				break; 
				
			case '=':     //OPTR栈顶元素是 "(" 且c是 ")"
				 Pop(OPTR,x);
                 c=getchar();
				 GetTop(OPTR,e);
                 break;    
			}  //switch
		} 
	}//while
	GetTop(OPND,e);
	return e;
}

//主函数   
void main(){ 
	int EndNum;
	printf("Please enter the arithmetic expression.End with #.  \n");
	EndNum=EvaluateExpression();
	printf("The results of is : %d \n",EndNum);

}  

以上代码仍不能很好实现,如有建议,敬请留言,谢谢!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值