表達式求值 C++版

#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;
}

点赞