利用栈将中缀算数表达式变换成后缀算术表达式并计算(0-9)

本文介绍了一个使用C++实现的后缀表达式计算器。该计算器通过栈来处理数学表达式,并能正确处理加、减、乘、除四种基本运算。文章详细展示了如何将中缀表达式转换为后缀表达式的过程,以及如何解析后缀表达式进行计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <stack>
#include <math.h>
#define maxsize 20
using namespace std;
class Calculator
{
public:
	Calculator(){while(s.empty()==false)s.pop();}
	void Run(char *ch);
	void Clear();
private:
	stack<int> s;
	void AddOperator(int value);
	bool Get2Operands(int& left,int& right);
	void DoOperator(char op);
};
void Calculator::DoOperator(char op)
//私有函数:取两个操作数,根据操作符op形成运算指令并计算
{
	int left,right,value;
	bool result;
	result=Get2Operands(left,right);//取两个操作数
	if(result==true)//如果操作数取成功,计算并进栈
		switch(op){
			case'+':value=left+right;s.push(value);break;//加
			case'-':value=left-right;s.push(value);break;//减
			case'*':value=left*right;s.push(value);break;//乘
			case'/':if(right==0.0){//若除0,报错,清栈
						cerr<<"Divide by 0!"<<endl;
						Clear();
					}
					else{
						value=left/right;s.push(value);
					}
					break;//没有除0,做除法
		}
	else Clear();//取操作数出错,清栈
}
bool Calculator::Get2Operands(int &left,int& right)
//私有函数:从操作数栈中取出两个操作数
{
	if(s.empty()==true){//检查栈空否
		cerr<<"缺少右操作数!"<<endl;//栈空,报错
		return false;
	}
	right=s.top();//取右操作数
	//cout<<"右操作数:"<<right<<endl;
	s.pop();//右操作数退栈
	if(s.empty()==true){//检查栈空否
		cerr<<"缺少左操作数!"<<endl;//栈空,报错
		return false;
	}
	left=s.top();//取左操作数
	//cout<<"左操作数:"<<left<<endl;
	s.pop();//左操作数退栈
	return true;
}
void Calculator::AddOperator(int value)
//私有函数:将操作数的值value进操作数栈
{
	s.push(value);
}
void Calculator::Run(char *ch)
//读字符串并求一个后缀表达式的值。以字符‘#’结束
{
	//char ch;
	int newOperand;
	char *p=ch;
	while(*p!='#'){
		//cout<<*p<<endl;
		switch(*p){
			case'+':
			case'-':
			case'*':
			case'/':DoOperator(*p);break;//是操作数,执行计算
			default://cin.putback(*p);//将字符放回输入流
				//cin>>newOperand;//重新读操作数
				newOperand=*p-48;
				AddOperator(newOperand);//将操作数放入栈中
		}
		p++;
	}
	cout<<"="<<s.top()<<endl;
}
void Calculator::Clear()
//清栈
{
	while(s.size()>0)
		s.pop();
}
int isp(char ch)
//栈内优先数
{
	int num=-1;
	switch(ch){
		case'#':num=0;break;
		case'(':num=1;break;
		case'*':
		case'/':
		case'%':num=5;break;
		case'+':
		case'-':num=3;break;
		case')':num=6;break;
	}
	return num;
}
int icp(char ch)
//栈外优先数
{
	int num=-1;
	switch(ch){
		case'#':num=0;break;
		case'(':num=6;break;
		case'*':
		case'/':
		case'%':num=4;break;
		case'+':
		case'-':num=2;break;
		case')':num=1;break;
	}
	return num;
}
void postfix()
//将中缀表达式转换为后缀表达式,表达式收尾字符均为‘#’
{
	stack<char> s;//定义栈的对象s,其元素为字符
	char ch='#',ch1,op,p[maxsize];
	int i=0;
	s.push(ch);//栈底存放‘#’
	cin.get(ch);//读入下一个字符
	while(s.empty()==false && ch!='#')
		if(isdigit(ch)){//判断加粗样式是否为操作数
			cout<<ch;
			p[i]=ch;i++;
			cin.get(ch);
		}
		else{
			ch1=s.top();//取栈顶操作符ch1
			if(isp(ch1)<icp(ch)){//新输入操作符ch优先级高
			加粗样式	s.push(ch);//进栈
				cin.get(ch);//读下一字符
			}
			else if(isp(ch1)>icp(ch)){//新输入操作符ch优先级低
				op=s.top();//退栈
				s.pop();
				cout<<op;
				p[i]=op;i++;
			}
			else{
				op=s.top();//输入操作符优先级等于栈顶优先级
				s.pop();
				if(op=='(')
					cin.get(ch);
			}
		}
		
		Calculator CAL;
		CAL.Run(p);
}
int main()
{
	postfix();
	system("pause");
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值