[数据结构][栈]N表达式求值

//书上缺失的太多 这个非常贴近 但是感觉很复杂?
//转载于 https://blog.csdn.net/libingbojava/article/details/81035975

#include<iostream>
#include<stdlib.h>
#define STACK_INIT_SIZE 100  //存储空间初始分配量 
#define STACKINCREMENT 10  //存储空间增量
using namespace std;
typedef  struct
{
	int *base;  //栈底指针 ,构造前和销毁后都为NULL
	int *top;  //栈顶指针
	int stacksize ; //当前以分配的存储空间 
 } SqStack_OPND;
 
 
typedef  struct
{
	char *base;  //栈底指针 ,构造前和销毁后都为NULL
	char *top;  //栈顶指针
	int stacksize ; //当前以分配的存储空间 
 } SqStack_OPTR;
 
 
bool   InitStack_OPND(SqStack_OPND &s)
{
	//构造一个空栈
	s.base = (int*) malloc(STACK_INIT_SIZE * sizeof(int) ) ;
	if(!s.base)  return false;
	s.top = s.base;
	s.stacksize = STACK_INIT_SIZE;
	return true;
} 
 
bool   InitStack_OPTR(SqStack_OPTR &s)
{
	//构造一个空栈
	s.base = (char*) malloc(STACK_INIT_SIZE * sizeof(char) ) ;
	if(!s.base)  return false;
	s.top = s.base;
	s.stacksize = STACK_INIT_SIZE;
	return true;
} 
 
 
char  GetTop_OPTR(SqStack_OPTR &s )
{
	//若栈不为空,返回字符e ,否则返回数值0 
	char e;
	if(s.top == s.base)  return 0;
	e = *(s.top-1);
	return e;
}
 
 
char  GetTop_OPND(SqStack_OPND &s )
{
	//若栈不为空,返回字符e ,否则返回数值0 
	int e;
	if(s.top == s.base)  return 0;
	e = *(s.top-1);
	return e;
}
 
 
bool  Push_OPTR(SqStack_OPTR &s  , char e)
{
	//插入e为新的栈顶元素
	if(s.top - s.base > s.stacksize)	{   //栈满,追加存储空间 
		s.base = (char*) realloc(s.base  , (s.stacksize + STACKINCREMENT)  * sizeof(char) );
		if(!s.base) return false;
		s.top =  s.base + s.stacksize;
		s.stacksize += STACKINCREMENT;
	 } //增加空间完毕 
	 
	 *s.top++ = e;
	 return true;
}
 
 
bool  Push_OPND(SqStack_OPND &s  , int e)
{
	//插入e为新的栈顶元素
	if(s.top - s.base > s.stacksize)	{   //栈满,追加存储空间 
		s.base = (int*) realloc(s.base  , (s.stacksize + STACKINCREMENT)  * sizeof(int) );
		if(!s.base) return false;
		s.top =  s.base + s.stacksize;
		s.stacksize += STACKINCREMENT;
	 } //增加空间完毕 
	 
	 *s.top++ = e;
	 return true;
}
 
 
bool Pop_OPTR(SqStack_OPTR &s , char &e)
{
	//若栈不为空,删除s的栈顶元素,用e返回其值,并返回true , 否则返回false
	if(s.top == s.base)  return false;
	e = * --s.top;
	return  true; 
}
 
 
bool Pop_OPND(SqStack_OPND &s , int &e)
{
	//若栈不为空,删除s的栈顶元素,用e返回其值,并返回true , 否则返回false
	if(s.top == s.base)  return false;
	e = * --s.top;
	return  true; 
}
 
 
//定义两个工作栈
//用来寄存运算符的栈   :  OPTR
//用来寄存操作数或运算结果的栈   :  OPND
SqStack_OPTR OPTR ;
SqStack_OPND OPND ;
 
int e;  //接收栈顶元素 GetTop() 和 Pop()中用到
 
char Precede(char  e , char c)  //根据算符优先关系表,返回三个优先关系之一 
{
		//规定, e 为01 ,c 为 02
		int convert_e , convert_c; //将e 和 c 转换为数字在进行比较,方便代码书写和理解
		
		//对e 进行转换 
		switch(e)
		{
			case '+' : convert_e = 1 ;  break;
			case '-' : convert_e = 2 ;  break;	
			case '*' : convert_e = 3 ;  break;
			case '/' : convert_e = 4 ;  break;
			case '(' : convert_e = 5 ;  break;
			case ')' : convert_e = 6 ;  break;
			case '#' : convert_e = 7 ;  break;
		} 
		
		
		//对c 进行转换 
		switch(c)
		{
			case '+' : convert_c = 1 ;  break;
			case '-' : convert_c = 2 ;  break;	
			case '*' : convert_c = 3 ;  break;
			case '/' : convert_c = 4 ;  break;
			case '(' : convert_c = 5 ;  break;
			case ')' : convert_c = 6 ;  break;
			case '#' : convert_c = 7 ;  break;
		} 
		
		if(convert_e == 1 && convert_c == 1)  return '>';
		if(convert_e == 1 && convert_c == 2)  return '>';
		if(convert_e == 1 && convert_c == 3)  return '<';
		if(convert_e == 1 && convert_c == 4)  return '<';
		if(convert_e == 1 && convert_c == 5)  return '<';
		if(convert_e == 1 && convert_c == 6)  return '>';
		if(convert_e == 1 && convert_c == 7)  return '>';
		
		
		
		if(convert_e == 2 && convert_c == 1)  return '>';
		if(convert_e == 2 && convert_c == 2)  return '>';
		if(convert_e == 2 && convert_c == 3)  return '<';
		if(convert_e == 2 && convert_c == 4)  return '<';
		if(convert_e == 2 && convert_c == 5)  return '<';
		if(convert_e == 2 && convert_c == 6)  return '>';
		if(convert_e == 2 && convert_c == 7)  return '>';
		
		
		if(convert_e == 3 && convert_c == 1)  return '>';
		if(convert_e == 3 && convert_c == 2)  return '>';
		if(convert_e == 3 && convert_c == 3)  return '>';
		if(convert_e == 3 && convert_c == 4)  return '>';
		if(convert_e == 3 && convert_c == 5)  return '<';
		if(convert_e == 3 && convert_c == 6)  return '>';
		if(convert_e == 3 && convert_c == 7)  return '>';
		
		
		
		if(convert_e == 4 && convert_c == 1)  return '>';
		if(convert_e == 4 && convert_c == 2)  return '>';
		if(convert_e == 4 && convert_c == 3)  return '>';
		if(convert_e == 4 && convert_c == 4)  return '>';
		if(convert_e == 4 && convert_c == 5)  return '<';
		if(convert_e == 4 && convert_c == 6)  return '>';
		if(convert_e == 4 && convert_c == 7)  return '>';
		
		
		if(convert_e == 5 && convert_c == 1)  return '<';
		if(convert_e == 5 && convert_c == 2)  return '<';
		if(convert_e == 5 && convert_c == 3)  return '<';
		if(convert_e == 5 && convert_c == 4)  return '<';
		if(convert_e == 5 && convert_c == 5)  return '<';
		if(convert_e == 5 && convert_c == 6)  return '=';
		if(convert_e == 5 && convert_c == 7)  return '0';  //出现语法错误是返回字符0  因为 (  和 # 不允许相继出现 
		
		
		if(convert_e == 6 && convert_c == 1)  return '>';
		if(convert_e == 6 && convert_c == 2)  return '>';
		if(convert_e == 6 && convert_c == 3)  return '>';
		if(convert_e == 6 && convert_c == 4)  return '>';
		if(convert_e == 6 && convert_c == 5)  return '0';   // 不允许出现 ) ( 的形式 
		if(convert_e == 6 && convert_c == 6)  return '>';
		if(convert_e == 6 && convert_c == 7)  return '>'; 
		
		
		if(convert_e == 7 && convert_c == 1)  return '<';
		if(convert_e == 7 && convert_c == 2)  return '<';
		if(convert_e == 7 && convert_c == 3)  return '<';
		if(convert_e == 7 && convert_c == 4)  return '<';
		if(convert_e == 7 && convert_c == 5)  return '<';
		if(convert_e == 7 && convert_c == 6)  return '0';  //# 和 ( 不允许同时相继出现 
		if(convert_e == 7 && convert_c == 7)  return '=';
} //Precede
 
char theta;  // 在Precede()函数判出> 的情况下, 存放从OPTR中出栈的运算符
 
//返回运算结果  theta为操作数  a 和 b 为运算符左值 和 右值 
int  Operate(int a , char theta , int b)
{
	switch(theta)
	{
		case '+' : return a+b;
		case '-' : return a-b;
		case '*' : return a*b;
		case '/' : return a/b;
	}
} 
 
bool In(char c)
{
	switch(c)
	{
		case '+' :
		case '-' :
		case '*' :
		case '/' :
		case '(' :
		case ')' :
		case '#' : return true;
	}
	return false;
}
 
 
 
int  EvaluateExpression()   //int 是返回表达式运算后的最终结果 
{
	char c;
	InitStack_OPTR(OPTR);   Push_OPTR(OPTR , '#');
	InitStack_OPND(OPND);   c = getchar();
	
	while( c != '#' || GetTop_OPTR(OPTR) != '#')
	{
		if(!In(c)) 
		{
			
			Push_OPND(OPND , c-48); c =getchar();  //不是运算符则进栈 
		}
		else
		{
			switch( Precede(GetTop_OPTR(OPTR) , c) )
			{
				case '<':  //栈顶元素优先权低
				{
					Push_OPTR(OPTR , c) ; c = getchar(); break;
				} 
				
				case '=':  //脱括号并接收下一个字符
				{
					char x; //接收退栈后的值 
					Pop_OPTR(OPTR , x) ;  c = getchar(); break;
				} 
				
				case '>':  //退栈并将结果存入栈
				{
					int a ,b;
					Pop_OPTR(OPTR , theta);
					Pop_OPND(OPND , b); Pop_OPND(OPND ,a);
					Push_OPND(OPND , Operate(a ,theta ,b));
					break;
				} 
			}//switch
		}
	} //while
	return GetTop_OPND(OPND);
} 
 
int main()
{
	cout<<"输入表达式,得出运算结果,输入以#结束,输入完毕请按回车!"<<endl;
	int result = EvaluateExpression();
	cout<<"表达式结果为:"<<endl;
	cout<<result<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俺叫西西弗斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值