《数据结构》 算法3.4 栈的应用---表达式求值

 该算法将操作数作为一个栈,运算符作为一个栈

1. 首先置操作数栈为空栈,表达式起始符'#'作为运算符栈的栈底元素

2. 依次读入表达式中每个字符,若是操作数则进操作数栈,反之进入运算符栈比较后作相应操作,最终得出结果

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
stack<char> OPTR;  //运算符栈 
stack<double> OPND;  //操作数栈 

//比较运算符(a代表运算符栈顶,b代表当前读入的运算符,以此进行相应的操作) 
char Precede(char a,char b)
{
	if(a=='+'||a=='-')  //比 + -运算符等级低的运算符 
	{
		if(b=='+'||b=='-'||b==')'||b=='#') return '>';  //默认+ -(* /)比本身的等级高(说明没有遇到括号之类的特别操作,直接计算) 
		else return '<';
	}
	else if(a=='*'||a=='/')  //比* / 运算符等级高的只有括号运算 
	{
		if(b=='(') return '<';
		else return '>';
	}
	else if(a=='(')  //当进入括号后,其他运算符都将包括在该括号内(在该括号未结束之前) 
	{
		if(b==')')  return '=';
		else return '<';
	}
	else if(a==')')  //括号结束  *理论正常输入情况下可能不会存在')'在运算符栈内的情况,因为'('在栈顶时遇到')'会弹出,从而在()运算完后消除出括号 
	{
		return '>'; 
	}
	else if(a=='#')  //结束标志 
	{
		if(b=='#')  return '=';
		else return '<';
	}
}

int In(char a)  //检查是否是运算符 
{
	return (a=='+'||a=='-'||a=='*'||a=='/'||a=='('||a==')'||a=='#');
}

double Oprator(double a,double b,char opra)  //对应的运算符进行对应的操作 
{
	switch(opra)
	{
		case '+':
			return (a+b);
		case '-':
			return (a-b);
		case '*':
		    return (a*b);
		case '/':
		    return (a/b);		
	}
}

int main()
{
	OPTR.push('#'); //运算符栈先存入'#' 
	char ch=getchar();
	while(ch!='#'||OPTR.top()!='#')  //当读到表达式末尾为'#'且运算符栈顶部也为'#'结束 
	{
		if(!In(ch)){  //当不是运算符时进操作数栈 
			double sum=0;
			while(!In(ch))  //对多位数进行计算读入 
			{
				sum=sum*10+ch-'0';
				ch=getchar();
			}
			OPND.push(sum);  //最终结果入栈 
		}
		else
		switch(Precede(OPTR.top(),ch)) 
		{
			case '<':  //栈顶元素优先权低 
				OPTR.push(ch);ch=getchar();  
				break;
			case '=':  //消除括号 
			    OPTR.pop();ch=getchar();	
			    break;
			case '>':  //运算 
			   char opar;double m,n;
			   opar=OPTR.top();OPTR.pop();
			   n=OPND.top();  OPND.pop();
			   m=OPND.top();OPND.pop();
			   OPND.push(Oprator(m,n,opar));
			   break;    
	    }
	}
	cout<<OPND.top()<<endl;  //输出结果 
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值