表达式求值 C++版

本文介绍了一个使用C++实现的类CExp,该类能够处理输入的数学表达式,并将其转换为后缀表达式,进而计算出表达式的结果。文章详细展示了如何通过栈来处理运算符的优先级,以及如何生成后缀表达式和计算最终结果。

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

#pragma once
#include <iostream>
using namespace  std;
#include <stack>
#include <vector>

class CExp
{
public:
	CExp(void);
	~CExp(void);
	// 获得运算符的优先级
	int GetPriority(char ch,bool bIn);
	void GetExp(void);
	void GeneralPostfixExp(void);
	int GetResult(void);
	int Calculate(char oper);
private:
	vector<char> m_expVect;
	vector<char>  m_postfixVect;
	stack<int> m_tempVal;
	stack<char> m_symbolStack;

};


.cpp文件
#include "Exp.h"
CExp::CExp(void)
{
	m_symbolStack.push('#');
}

CExp::~CExp(void)
{
}

// 获得运算符的优先级,bIn = ture;表示在栈内的优先级,否则表示栈外的优先级
int CExp::GetPriority(char ch, bool bIn)
{
	switch(ch)
	{
	case '+':
	case '-':
		return 2;
	case '*':
	case '/':
		return 3;
	case '(':
		{
			if (bIn)
			{
				return 1;
			}
			else
			{
				return 4;
			}
		}
	case ')':
		return 1;
	case '#':
		return 0;
	default:
		return -1;
	}
}

void CExp::GetExp(void)
{
	cout<<"请输入表达式以#号结尾:";
	char ch;
	do 
	{
		cin>>ch;
		m_expVect.push_back(ch);
	} while (ch != '#');
}


void CExp::GeneralPostfixExp(void)
{
	vector<char>::iterator it = m_expVect.begin();
	while(it != m_expVect.end())
	{
		if (isdigit(*it))
		{
			while(isdigit(*it))
			{
				m_postfixVect.push_back(*it);
				it++;
			}
			//加一个#号分隔符,表示前面的几个字符可以转换成一个整数
			m_postfixVect.push_back('#');
		}


		if (it == m_expVect.end())
		{
			return;
		}

		switch(*it)
		{
		case '+':
		case '-':
		case '*':
		case '/':
		case '(':
			//比较此运算符和栈内的运算符的优先级,如果栈内优先级小于*it的优先级则将*it压入符号栈,否则将符号栈循环出栈直到栈内符号优先级大于*it,此时将*it压栈
			if (GetPriority(*it, 0) > GetPriority(m_symbolStack.top(), 1))
			{
				m_symbolStack.push(*it);
			}
			else
			{
				m_postfixVect.push_back(m_symbolStack.top());
				m_symbolStack.pop();
				//如果符号栈不为空,且栈内运算符的优先级大于等于*it的优先级,则将栈内的符号弹出并压到后缀表达式中
				while(m_symbolStack.top() != '#' && GetPriority(m_symbolStack.top(), 1)>=GetPriority(*it, 0))
				{
					m_postfixVect.push_back(m_symbolStack.top());
					m_symbolStack.pop();
				}
				m_symbolStack.push(*it);
			}
			break;
		case ')':
			//将符号栈中的符号依次出栈并压到后缀表达式中,直到符号栈的栈顶位左括号
			while(m_symbolStack.top() != '(')
			{
				m_postfixVect.push_back(m_symbolStack.top());
				m_symbolStack.pop();
			}
			//弹出左括号
			m_symbolStack.pop();
			break;
		default:
			//将数字压入栈
			m_postfixVect.push_back(*it);
			break;
		}
		it++;
	}
	//因为输入表达式的最后一个字符位#,所以要将#号从后缀表达式中移除
	m_postfixVect.pop_back();

	//将符号栈中的符号全部出栈
	while (m_symbolStack.top() != '#')
	{
		m_postfixVect.push_back(m_symbolStack.top());
		m_symbolStack.pop();
	}
	m_symbolStack.pop();
}

int CExp::GetResult(void)
{
	vector<char>::iterator it = m_postfixVect.begin();
	while(it != m_postfixVect.end())
	{
 		int val=0;
 		//生成整数
 		while (isdigit(*it))
 		{
 			while(isdigit(*it))
 			{
 				val *= 10;
 				val += *it-'0';
 				it++;
 			}
 			m_tempVal.push(val);
			it++; //将#号滤过
			val = 0;
 		}

		m_tempVal.push(Calculate(*it)); //将计算结果压入临时栈中
		it++;
	}
	return m_tempVal.top();
}

int CExp::Calculate(char oper)
{
	int res;
	int left, right;
	right = m_tempVal.top();  //注意顺序 先弹出的数为右边的操作数
	m_tempVal.pop();
	left = m_tempVal.top();
	m_tempVal.pop();
	switch(oper)
	{
	case '+':
		res = left+right;
		break;
	case '-':
		res = left-right;
		break;
	case '*':
		res = left*right;
		break;
	case '/':
		res = left/right;
		break;
	}
	return res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值