栈实现表达式求值

16 篇文章 0 订阅

本片文章主要介绍的表达式求值方法是“算符优先法”。
算符优先法就是根据运算优先关系的规定来实现对表达式的编译或解释执行的。
话不多说直接看详细代码:

#include <iostream>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAXSIZE 100

using namespace std;
typedef char SElemType;
typedef int NElemType;
typedef int Status;

//储存运算符的栈
typedef struct{
	char* base;
	char* top;
	int stackSize;
}SqStack_optr; 


string s; //用来储存完整地表达式

//储存操作数的栈
typedef struct{
	NElemType *base;
	NElemType *top;
	int stackSize;
}SqStack_opnd;



//运算符栈的初始化 
int InitStackS(SqStack_optr& S)
{
	S.base=new SElemType[MAXSIZE];
	if(!S.base)  return false;
	S.top=S.base;
	S.stackSize=MAXSIZE;
	return OK;
}

//操作数栈的初始化 
int InitStackN(SqStack_opnd& S)
{
	S.base=new NElemType[MAXSIZE];
	if(!S.base)  return false;
	S.top=S.base;
	S.stackSize=MAXSIZE;
	return OK;
}

//运算符栈入栈操作 
int PushS(SqStack_optr& S,SElemType e)
{
	if(S.top-S.base==S.stackSize)
	return ERROR;
	*S.top++=e;
	return OK;
}

//操作数栈入栈操作 
int PushN(SqStack_opnd& S,NElemType e)
{
	if(S.top-S.base==S.stackSize)
	return ERROR;
	*S.top++=e;
	return OK;
}

//运算符栈出栈操作
int PopS(SqStack_optr& S,SElemType& e)
{
	if(S.top==S.base )//栈空了
	return ERROR;
	e=*--S.top;
	return OK; 
	
 } 
 
 //操作数栈出栈操作 
 int PopN(SqStack_opnd& S,NElemType& e)
{
	if(S.top==S.base )//栈空了
	return ERROR;
	e=*--S.top;
	return OK; 
	
 } 

//运算符栈取栈顶元素 
char GetTopS(SqStack_optr S)
{
	char e;
	if(S.top==S.base)
	return ERROR;
	e=*(S.top-1);
	return e;
	
 } 
 
 //操作数栈取栈顶元素 
 int GetTopN(SqStack_opnd S)
{
	int e;
	if(S.top==S.base)
	return ERROR;
	e=*(S.top-1);
	return e;
 } 
  
//判断当前字符是否为运算符 
int In(SElemType c)
{
	switch(c)
    {
    	case '+':   
        case '-':  
        case '*':   
        case '/':   
        case '(':   
        case ')': 
        case '=': 
                 return 1;
		 default:
		         return 0;	
	}
}


//判断运算符的优先级:t1>t2,opnd出栈,运算后再入栈;否则 t2入栈;t1=t2则去掉括号 
char Precede(char t1,char t2)
{
	int i,j;
	char pre[7][7]={// +   -   *   /   (   )   = 
		             {'>','>','<','<','<','>','>'},  
                     {'>','>','<','<','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'>','>','>','>','<','>','>'},  
                     {'<','<','<','<','<','=','0'},  
                     {'>','>','>','>','0','>','>'},  
                     {'<','<','<','<','<','0','='}}; 
                
    switch(t1){
    	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(t2){
    	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 pre[i][j];
 } 
 
 
int Operate(int a,char theta,int b)
{
	int c;
	switch(theta)
	{
		case'+':
			c=a+b;
			break;
		case'-':
			c=a-b;
			break;
		case'*':
			c=a*b;
			break;
		case'/':
			c=a/b;
			break;
	} 
	return c;
 } 

//ch是用来储存按字符输入的表达式
int evaluate()
{
	SqStack_optr OPTR;
	SqStack_opnd OPND;
	
	InitStackS(OPTR);
	PushS(OPTR,'=');
	InitStackN(OPND);
	char ch,theta;
	int a,b,t,e;
	int now=0;//记录上一个状态是数字还是运算符 
	char x;
	cin>>ch;//读取第一个字符 
	s+=ch;
	while(ch!='='||GetTopS(OPTR)!='=')//判断表达式是否读取完毕 
	{
		if(!In(ch))//判断当前读取的字符是操作数还是运算符 
		{
			if(now==1)
			{
				PopN(OPND,e);
				t=ch-'0';
				PushN(OPND,e*10+t);
				now=1;
			}
			else
			{
				PushN(OPND,ch-'0');
			    now=1;
			}
		
			cin>>ch;
			s+=ch;
		}
		else{
			now=0;
			switch(Precede(GetTopS(OPTR),ch))//比较ch的与OPTR栈顶元素的优先级
			{
				case'<':
					    PushS(OPTR,ch);
					    cin>>ch; //读取下一位字符并将指针向后偏移一位
					    s+=ch;
					    break;
				
				case'>':
					    PopS(OPTR,theta); 
					    PopN(OPND,b);
					    PopN(OPND,a);
					    PushN(OPND,Operate(a,theta,b));
					    break;
			
				case'=':
					    PopS(OPTR,x);//去掉运算符栈的左括号 
					    cin>>ch; //读取下一位字符并将指针向后偏移一位
					    s+=ch;
					    break;
			}
		}
	}
	return GetTopN(OPND);
 } 

int main()
{
	cout<<"请输入表达式以=结束:"<<endl;
	int ans=evaluate();
	cout<<"表达式:"<<s;
	cout<<ans;
	return 0;
}

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值