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