终于想要实现一些东东了,先从简单的做起吧,先实现一个简单的四则运算器,假定输入的表达式正确(偷懒而已)。
首先需要一个栈结构,因为很简单,就随便写了一个
template<class T>
class CStack{
private:
struct CStack_Item{
CStack_Item* pPrev;
T t;
};
public:
CStack() : m_pTop(NULL), m_nsize(0){};
~CStack(){};
private:
CStack_Item* m_pTop; //保存栈顶
int m_nsize;
public:
//出栈,如果栈为空,返回false
bool Pop(T& t){
if(m_pTop == NULL)
return false;
t = m_pTop->t;
CStack_Item* tmp = m_pTop;
m_pTop = m_pTop->pPrev;
delete tmp;
m_nsize--;
};
//入栈
void Push(const T& t){
CStack_Item* item = new CStack_Item;
item->t = t;
if(m_pTop == NULL)
item->pPrev = NULL;
else
item->pPrev = m_pTop;
m_pTop = item;
m_nsize++;
};
bool Top(T& t){
if(m_pTop == NULL)
return false;
t = m_pTop->t;
return true;
};
int size(){
return m_nsize;
};
};
先是设定符号的优先级然后就是
//设定符号优先级
enum {RIGHT_PARENTHESIS = 1, PLUS_MINUS, MUTIPLY_DEVIDE, LEFT_PARENTHESIS, OPREATE_ERROR};
本来想在这里加上一些检查,嫌麻烦(偷懒啊)
//返回优先级
int GetPriority(TCHAR chOp){
int OpPriority = 0;
switch(chOp)
{
case _T('+'):
case _T('-'):
OpPriority = PLUS_MINUS;
break;
case _T('*'):
case _T('/'):
OpPriority = MUTIPLY_DEVIDE;
break;
case _T('('):
OpPriority = LEFT_PARENTHESIS;
break;
case _T(')'):
OpPriority = RIGHT_PARENTHESIS;
break;
default:
OpPriority = OPREATE_ERROR;
break;
}
return OpPriority;
};
int InfixToSuffixExpression(const wstring& szInfixExpression, wstring& szSuffixExpression){
CStack<TCHAR> op;
int nPos = 0;
wstring szDigit; //上一个操作符
int OpLastPriority = 0; //保存上一个符号的优先级
int OpPriority = 0;
wstring szOp;
TCHAR chOp;
szSuffixExpression = _T("");
for(int i = 0; i < szInfixExpression.size(); i++)
{
switch(szInfixExpression[i])
{
case _T('+'):
case _T('-'):
case _T('*'):
case _T('/'):
case _T('('):
case _T(')'):
//插入当前数字
szDigit = szInfixExpression.substr(nPos, i - nPos);
if(!szDigit.empty())
{
szSuffixExpression += szDigit;
szSuffixExpression += _T(" ");
}
OpPriority = GetPriority(szInfixExpression[i]);
if(op.Top(chOp))
{
OpLastPriority = GetPriority(chOp);
if(OpLastPriority == LEFT_PARENTHESIS) //左括号在表达式中优先级最高,在堆栈中最低
OpLastPriority = RIGHT_PARENTHESIS;
if(OpPriority <= OpLastPriority)
{
while(op.Pop(chOp)){
if(chOp != _T('('))
{
szSuffixExpression += chOp;
szSuffixExpression += _T(" ");
}
else
break;
}
}
}
if(OpPriority != RIGHT_PARENTHESIS)
op.Push(szInfixExpression[i]);
nPos = i + 1;
break;
}
}
szSuffixExpression += szInfixExpression.substr(nPos, wstring::npos);
szSuffixExpression += _T(" ");
while(op.Pop(chOp))
{
if(chOp != _T('('))
{
szSuffixExpression += chOp;
szSuffixExpression += _T(" ");
}
}
return 0;
};