四则运算器
终于想要实现一些东东了,先从简单的做起吧,先实现一个简单的四则运算器,假定输入的表达式正确(偷懒而已)。
首先需要一个栈结构,因为很简单,就随便写了一个
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; };