Calculator设计文档.doc

上传人:精*** 文档编号:963027 上传时间:2024-03-19 格式:DOC 页数:13 大小:277.76KB
下载 相关 举报
Calculator设计文档.doc_第1页
第1页 / 共13页
Calculator设计文档.doc_第2页
第2页 / 共13页
Calculator设计文档.doc_第3页
第3页 / 共13页
Calculator设计文档.doc_第4页
第4页 / 共13页
Calculator设计文档.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

1、一、整体设计【View层】:负责接收用户输入、将用户的输入序列传给controller层,然后等待controller返回要回显的东西(可以是正在输入的一串数字,也可以是中间结果)。【Controller层】:负责接收view传来的输入(字符序列),并根据序列特征进行解析(是否根据优先级计算某部分中间结果,是否是异常的不该回显的符号等),如果要计算中间结果就交给module层计算并等待其返回,最后将要回显的字符序列回传给view。【Module层】:负责接收来自controller的计算任务,进行各种一次运算(加、减、乘、除、单目运算等),将计算结果迅速返回给controller(如果是不可能

2、的计算任务,比如div 0,得返回特定的错误符号)。用户输入Module(专职计算)Controller(解析序列)View 接收输入的单个符号 回传需要显示的东西 接收计算任务 回传计算结果(必要时是错误符号) 二、接口设计1、Controllerclass CalculatorControlpublic:CalculatorControl(ICalculatorModel *pCalculatorModel);CalculatorControl(void);/接收用户指令string ReceiveCommand(COMMAND stCommand); /设置计算器的模式void SetC

3、alculatorForm(CALCULATOR_FORM emStatus); /获取计算器的模式CALCULATOR_FORM GetCalculatorForm(void); /获取用于View显示的数据string GetStringToDisplay(void);protected:/初始化void InitControl(); /获取数字按键对应的stringstring GetOperatorNumber(OPERATOR_SET emOperator); /获取操作符的优先级int GetOperatorPriority(OPERATOR_SET emOperator); /处

4、理不同的指令void DisposeCommand(COMMAND stCommand); /检测操作符栈中是否存在指定符号bool CheckOperatorInStack(OPERATOR_SET emOperator); CALC_RESULT_STATUS DoBinOperate(string &strErrMsg);CALC_RESULT_STATUS DoUnaryOperate(string &strErrMsg);void PushToOperatorStack(OPERATOR_SET emOperator);void PushToOperandStack(string s

5、trOperand);CALC_RESULT_STATUS ProcBinOperator(OPERATOR_SET emBinOp);CALC_RESULT_STATUS ProcUnrayOperator(OPERATOR_SET emUnrayOp);void ProcLeftBracket(void);CALC_RESULT_STATUS ProcRightBracket(void);private:/操作数栈vector m_vectorOperandStack; /操作符栈vector m_vectorOperatorStack; /记录上次操作:,操作数栈;,操作符栈;,尚未入栈

6、的操作数CONTROL_STATUS m_emControlStatus; /记录最后一次运算的右操作数string m_strLastRightOperand; /记录最后一次运算的操作符OPERATOR_SET m_emLastOperator; /尚未入栈的操作数string m_strInputOperand; /尚未入栈操作数的状态INPUT_STATUS m_emInputStatus; /计算器的模式:,标准模式;,科学模式CALCULATOR_FORM m_emCalculatorStatus; /数字按键与string对照表OperatorNumberMap m_mapOpe

7、ratorNumberMap; /用于View显示的数据string StringToDisplay; /底层运算接口ICalculatorModel *m_pCalculatorModel; ;2、Model接收计算任务并回传计算结果enum CALC_RESULT_STATUSCALC_RESULT_NORMAL = 0,CALC_RESULT_ERROR,CALC_RESULT_UNUSUAL;class ICalculatorModelpublic:virtual CALC_RESULT_STATUS CalculateData(const string &lhs, const str

8、ing &rhs, OPERATOR_SET emOperator, string &CalcResult) = 0;#ifdef _UNIT_TESTclass SimpleCalculatorModel : public ICalculatorModelpublic:virtual CALC_RESULT_STATUS CalculateData(const string &lhs, const string &rhs, OPERATOR_SET emOperator, string &CalcResult);#endif / _UNIT_TESTclass CalculatorModel

9、 : public ICalculatorModelpublic:CalculatorModel(void);CalculatorModel(void);virtual CALC_RESULT_STATUS CalculateData(const string &lhs, const string &rhs, OPERATOR_SET emOperator, string &CalcResult);三、实现细节1、View 用户每点击一个按钮,就将该按钮对应的ID(在EMUN_OP_SET枚举类型中集体定义)传递给Controller:ReceiveChar(ID),并等待该回显的结果。以输入

10、序列为“1+2*3+”为例:输入1,传给controller,controller返回1;输入+,传给controller,controller返回1;输入2,controller返回2;输入*,controller返回2;输入3,controller返回3;输入+,controller返回一个中间结果7。2、Controller通过双栈(数字栈和运算符栈),进行解析输入序列,并灵活应各种怪异的序列。双栈原理:如果接收到一个运算符,先与运算符栈中的栈顶运算符进行比较,如果当前运算符的优先级=栈顶运算符优先级,就从数字栈中弹出两数字进行运算(交给Module计算),而且所有该算的都应该算完(比如

11、:已经输入1+2*3,当输入+时,应该把2*3=6计算之后接着计算1+6=7)。四、如何应对怪异序列用户不停的逐个点击按钮,controller源源不断的接收符号,当前待接收的符号和controller的状态决定了下一步该做哪一系列的处理,并且针对该符号的这一系列处理结束后会赋予controller一个新的状态,以迎接下一个即将到来的符号。总的来说就是哪类符号面临哪种状态会做出一系列套路般的处理,处理完后会赋予一种新的状态。(1) Controller的状态可以分为三种:1、 STATUS_OPERAND:表示计算器刚刚启动或上次有了一个中间结果。2、 STATUS_OPERATOR:表示上次

12、输入了一个运算符(单目、双目、括号)3、 STATUS_TEMPSTRING:表示上一次输入的是数字或者小数点。(2) 各种符号可以分为六类,下面举一些异常的例子加以明:1、 单目运算符:永远不会进运算符栈,会及时计算出来输入“5+cos”,那么会变成“5+cos5”,也就是说单目是待接收的符号并且上次是STATUS_OPERATOR(运算符状态),那么该单目符号会把栈顶的数字当做操作数进行计算并将中间结果压入数字栈。再如输入“5(cos”,会变成“(cos5”。2、 左括号待接收符号是(时,得在逻辑上保证:A、 左括号前不可能紧邻数字;B、 左括号后不可能紧邻运算符。针对A,如果当前状态为S

13、TATUS_OPERAND(上次输入了一个数字),那么左括号进运算符栈并将状态保持为STATUS_ OPERAND,就在逻辑上将上次的数字放在括号内了输入“5(”就变成“(5”;针对B,如果当前状态是STATUS_OPERATOR(上一次输入的是运算符),那么左括号进运算符栈并在数字栈中压入0,将状态保持为STATUS_ OPERAND,就在逻辑上保证了左括号后始终有个数字存在输入“(+”变成“(0+”。3、 右括号待接收符号是)时,得在逻辑上保证:A、 前面必须有能匹配的左括号;B、 右括号前不可能紧邻运算符针对A,如果运算符栈中不存在左括号,那么就忽略右括号的输入(因为右括号遇到左括号会计

14、算他们中间的局部结果并消掉括号,运算符栈中最多只可能存在一个左括号);针对B,如果当前状态时STATUS_OPERATOR,那么就复制一份数字栈顶元素,输入“(8*)”变成“(8*8)”。4、 双目运算符待接收符号是双目时,得保证:A、 不可能存在相邻的多个双目运算符B、 前面该算的局部表达式都应该得到计算 针对A,如果当前状态是STATUS_OPERATOR(上次输入了运算符),那么就用待接收的双目覆盖运算符栈顶的元素输入“5+*”变成“5*”;针对B,就得将待接收的双目符号优先级与运算符栈顶的进行比较,将前面能算的都算完输入“2+3*3+”,此时在逻辑上会变成“11+”。5、 等号待接收符

15、号是“=”时,得一口气将前面所有的表达式算完。另外还有两种特殊情况:A、 运算符栈为空B、 =前面紧邻的是双目运算符针对A,如果LastOperator为空,表明之前没有进行任何运算,忽略,否则将LastOperator压入运算符栈且LastOperand压入数字栈,然后调用双目计算函数;针对B,以“5+=”为例,会变成“5+5=”且记录LastOperand=5、LastOperator=+,如果接着再输入=,那么就跳回针对A的处理流程。6、数符(数字或小数点) 待接收符号是数符时,得注意两点:A、 一个数字不可能存在多个小数点B、 如果当前状态为STATUS_OPERAND,那么再输入数字就覆盖数字栈顶元素五、各类符号所对应的套路般处理流程接收输入序列后的解析流程如下:双目运算符单目运算符等号运算符输入数字 左括号 右括号

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他资料

版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如有侵权请立即联系:2622162128@qq.com ,我们立即下架或删除。

Copyright© 2022-2024 www.wodocx.com ,All Rights Reserved |陕ICP备19002583号-1 

陕公网安备 61072602000132号     违法和不良信息举报:0916-4228922