四则运算的C++实现

来源:互联网 发布:阳光民间借贷网络借贷 编辑:程序博客网 时间:2024/06/05 00:47

一个很基本的问题,总是在重复发明轮子,为了不总讨论这种月经问题,今天彻底终结这个问题吧。

大体分两步:去掉括号,并转化为后缀队列,然后计算这个队列


BaseCalc.h:

#pragma onceenum CalcType{CalcType_None,CalcType_Number,CalcType_Operator_Plus,CalcType_Operator_Multiply,CalcType_Operator_Left_Parenthesis,CalcType_Operator_Minus = 0x80000000 + CalcType_Operator_Plus,CalcType_Operator_Divide = 0x80000000 + CalcType_Operator_Multiply,};class CBaseCalc{public:CBaseCalc(char cOpr){m_nValue = cOpr;if ('+' == cOpr) m_nType = CalcType_Operator_Plus;else if ('*' == cOpr) m_nType = CalcType_Operator_Multiply;else if ('(' == cOpr) m_nType = CalcType_Operator_Left_Parenthesis;else if ('-' == cOpr) m_nType = CalcType_Operator_Minus;else if ('/' == cOpr) m_nType = CalcType_Operator_Divide;else m_nType = CalcType_None;}CBaseCalc(CalcType nType){ m_nType = nType; m_nValue = 0; }virtual ~CBaseCalc(){}double GetValue(){ return m_nValue; }void SetValue(double d){ m_nValue = d; }CalcType GetType(){ return m_nType; }private:double m_nValue;CalcType m_nType;};double Calculate(CalcType nType,CBaseCalc& a, CBaseCalc&b){double dRet = 0;switch (nType){case CalcType_None:break;case CalcType_Number:break;case CalcType_Operator_Plus:return a.GetValue() + b.GetValue();break;case CalcType_Operator_Multiply:return a.GetValue() * b.GetValue();break;case CalcType_Operator_Left_Parenthesis:break;case CalcType_Operator_Minus:return a.GetValue() -b.GetValue();break;case CalcType_Operator_Divide:return a.GetValue() /b.GetValue();break;default:break;}return dRet;}bool operator <(CBaseCalc& a, CBaseCalc& b){int nA = a.GetType() & 0x7FFFFFFF;int nB = b.GetType() & 0x7FFFFFFF;return nA<nB;}

main.cpp

#include <string>#include <stack>#include <queue>using namespace std;#include "BaseCalc.h"char * express = "1+2*3-(4*5+6)/7-8/9";bool IsNum(int a){if (a>='1'&&a<='9'){return true;}return false;}double CalcPostFix(queue<CBaseCalc>& input_queue){stack<CBaseCalc> stackTmp;do{CBaseCalc a = input_queue.front();input_queue.pop();if (a.GetType() != CalcType_Number){printf("%c ", (int)a.GetValue());CBaseCalc nNum1 = stackTmp.top();stackTmp.pop();CBaseCalc nNum2 = stackTmp.top();stackTmp.pop();double dRet = Calculate(a.GetType(), nNum2, nNum1);CBaseCalc nc(CalcType_Number);nc.SetValue(dRet);stackTmp.push(nc);}else{printf("%f ", a.GetValue());//NumCalc nc;//nc.SetValue(a.GetValue());stackTmp.push(a);}} while (!input_queue.empty());return stackTmp.top().GetValue();}void Fun(){queue<CBaseCalc> queuePostFix;stack<CBaseCalc> stackOpr;char* pCur = express;int nLen = strlen(express);int nCur = 0;int nLast = 0;string aNum;char cLast = 0;while (nCur <= nLen){pCur = express + nCur++;if (IsNum(*pCur)){aNum += *pCur;}else{if (!aNum.empty()){CBaseCalc bc(CalcType_Number);int nValue = atoi(aNum.c_str());bc.SetValue(nValue);queuePostFix.push(bc);aNum = "";}if (stackOpr.empty()){stackOpr.push(*pCur);}else{char cOpr = *pCur;cLast = cOpr;if ('(' == cOpr){stackOpr.push(cOpr);}else if (')' == cOpr){do{CBaseCalc a = stackOpr.top();stackOpr.pop();if (a.GetType() != CalcType_Operator_Left_Parenthesis){queuePostFix.push(a);}else{break;}} while (true);}else{while (true){CBaseCalc a = stackOpr.top();if (a.GetType() == CalcType_Operator_Left_Parenthesis){stackOpr.push(cOpr);break;}CBaseCalc b(cOpr);if (a<b){stackOpr.push(b);break;}else{queuePostFix.push(a);stackOpr.pop();}if (stackOpr.empty()){stackOpr.push(cOpr);break;}}}}}//nCur++;}printf("\n");double dRet=CalcPostFix(queuePostFix);printf("\n%s = %f\n", express, dRet);}int _tmain(int argc, _TCHAR* argv[]){Fun();return 0;}

本着开源精神送给后来程序员,没有深度测试难免小BUG,希望学习者也是取其精华,修改别人bug也是自己提高的过程嘛。


0 0
原创粉丝点击