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