1、需要一台计算机装有visual C+。4.分析与实现对于中缀表达式,一般运算规则如下:(1) 先乘方,再乘除,最后加减;(2) 同级运算从左算到右;(3) 先括号内再括号外;(4) 用到的头文件”utility.h”,”lk_stack.h”,”node.h”,”calculator.h”.根据实践经验,可以对运算符设置统一的优先级,从而方便比较。表中给出了包括加、减、乘、除、求余、左括号、右括号和分界符的优先级。运算符=(、)+、*、/%优先级1245上面讨论的的+、为双目运算符,如为单目运算符,编程实现时,可在前面加上0而转化为双目运算符。如在+、的前一个字符(如当前字符不是运算符时,规定
2、用0表示)为=或(,则为单目运算符。具体实现算法时,可设置两个工作栈,一个为操作栈,一个为操作符栈optr,另外一个为操作数栈opnd,算法基本思路如下:(1) 将optr栈和opnd栈清空,在optr栈中加入一个=。(2) 从输入流获取一字符ch,循环执行步骤(3)至步骤(5)直到求出表达式的值为止。(3) 取出optr的栈顶optrTop,当optrTop=且ch=时,整个表达式求值完毕,这时opnd栈的栈顶元素为表达式的值。(4) 若ch不是操作符,则字符放回输入流(cin.putback),读操作数operand;将operand加入opnd栈,读入下一个字符ch。(5) 如ch是操作
3、符,按如下方式进行处理:a.如果ch为单目运算符,则在ch前面加上操作数0,也就是将0入opnd栈;b.如果optrTop与ch不匹配,例如optrTop=)且ch=(,显示错误信息;c.如果optrTop=(且ch=),则从optr退出栈顶的(,去括号,然后从输入流中读入字符并送入ch;d.如果ch=(活optrTop比ch 的优先级低,则ch入optr栈,从输入中取下一字符ch;e.如果optrTop大于或等于ch的优先级,则从opnd栈退出left和right,从optr栈退出theta,形成运算指令(left)theta (right),结果如opnd栈。对于界面处理:(1)用文件流建
4、立一个小小的界面,美化处理一些操作,文件名为dd.txt/dd.txt文档内容 * * * * * * * * * * * * * 欢迎进入运算界面 * * * * * * * * * * * * * * 请选择: * 1.开始运算 * * 2.退出界面 * 对于运算处理:(1)通过运用栈和队列的特性,实现各种功能 。本类通过一系列的扩展实现各种出现的运算情况处理 /calculator.h# ifndef CALCULATOR_H# define CALCULATOR_H#include lk_stack.htemplateclass Calculatorprivate: LinkStack
5、 opnd;char optr; char GetChar()/从输入流中跳过空格,换行符及制表符获取一字符 char c; cinc; return c; int OperPrior(char op); /要自己写的函数 void Get2Operands(ElemType &left,ElemType &right); ElemType Operate(ElemType left,char op,ElemType right); bool IsOperator(char ch);public: Calculator() ; virtual Calculator() ; void Run()
6、;/使用switch语句int Calculator:OperPrior(char op) switch(op) case = return 1;( return 2;)+ return 3;-* return 4;/% return 5;/调用2次出栈函数,一定要先出右数,再出左数!void CalculatorGet2Operands(ElemType &right) opnd.Pop(right); opnd.Pop(left);/采用switch语句ElemType CalculatorOperate(ElemType left,char op,ElemType right) retu
7、rn left+right; return left-right; return left*right; return left/right; return int(left)%int(right); /输入数为浮点数,要强制转换为整数! return pow(left,right);bool Calculatoroperand; opnd.Push(operand); priorChar=0 ch=GetChar(); else if(!IsOperator(ch) throw else if(priorChar=|priorChar=)&(ch=) opnd.Push(0); priorC
8、har= if(optrTop=ch=|optrTop= throw else if(optrTop= if(!optr.Pop(optrTop) throw ch=GetChar(); else if(ch=|OperPrior(optrTop)OperPrior(ch) optr.Push(ch); priorChar=ch; else optr.Pop(op) throw ElemType left,right; Get2Operands(left,right); opnd.Push(Operate(left,op,right); if(!opnd.Top(operand) throw
9、cout 运算结果为:operandendl;#endif主函数功能:(1) 应用dd.txt建立小小界面;(2) 针对各种出错情况进行智能处理;(3) 实现本次计算基本呢操作/main主函数#includeutility.hcalculator.hint main()/第一部分进行界面处理,通过文件流的方式 char a100; ifstream in(dd.txt for(int i=1;i19;i+) in.getline(a,100); couta in.close(); char d100; while(true)/此方法可处理出现的一般不同错误 d; if (d0=1) break
10、; else if(d0=2) coutcout已退出界面!exit(0); else cout选择错误,请重新选择! /第二部分进行运算处理 char c;请输入表达式: Calculator myCalculator;输入形式如1(没有括号加减乘除):4+5-8+8/2+6*1=输入形式如2(加括号加减乘除):4*(7+1)/2+3-2=输入形式如3:+45= myCalculator.Run(); while(true)endl你是否要继续(y,n)? if(c=n cout运算已经结束,已退出程序! return 0; else if(c=y break;*你的输入错误,请重新输入:*运行结果:(1)一般成功运行:有括号的加减乘除,没有括号的加减乘除,单目运算(2)跳过空格,制表符,换行符继续运行(3)选择进入界面输错处理(4).输入选择是否继续出错处理5. 课程设计体会与感悟本次课程设计需要涉及到比较多的知识,为了美化界面用了文件流,让我有加深了对文件流的认识。算术的操作用了栈,结点类,让我更熟悉了栈后进先出以及其他类的的特点。1、该程序不只能运算整数,也能处理输入的负数2、可以一定的处理非法输入3、几种线性表(队列、栈、数组、链表)从根本上说可以实现同一个功能,只是难易程度的问题,熟悉各线性表的特点有助于快速选择简单的方法。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2