2简单计算器的实现

上传人:d**** 文档编号:51498263 上传时间:2022-01-26 格式:DOCX 页数:4 大小:15.41KB
收藏 版权申诉 举报 下载
2简单计算器的实现_第1页
第1页 / 共4页
2简单计算器的实现_第2页
第2页 / 共4页
2简单计算器的实现_第3页
第3页 / 共4页
资源描述:

《2简单计算器的实现》由会员分享,可在线阅读,更多相关《2简单计算器的实现(4页珍藏版)》请在装配图网上搜索。

1、2 简单计算器的实现程序 2.1 是计算器的主程序。我们将要处理的中缀表达式的字符串设为按行输入的,每 一行最多可容纳 80 个字符 ( 因 LineLength = 80 )。每次处理一行,为了简单起见,设计算 的对象为类型为 int 的正整数。通过调用类 Evaluator 的成员函数 GetValue 完 成计算功能,并打印输出。类 Evaluator 的说明,请参阅程序 2.1 。它使用了二个堆栈,一个是用于保 存运算符的堆栈 OpStack:另一个是保存操作数数值的堆栈PostFixStack ,注意程序本身并不输出后缀式, 而直接得到是最后的结果。 为了区分在输入时得到的各种不同的

2、符号的含义, 设立了枚举类型 enum。其中:OPAREN 、 CPAREN 、 EXP、 MULT 、 DIV 、 PLUS 、 MINUS 分别表示开括号、闭括号、乘方、乘、除、加、减。这些运算符表示要进行相应的运算。它 们的优先级规定参见数组 PrecTable ,优先数越大则优先级越高。乘方、乘和除的优先数 分别为 6、 5 及 3、 4,而加、减的优先数为 1、2,体现了乘方、乘和除、加和减的计算优 先级依次递减。在同样为乘、除或加、减时,栈顶算符(在表达式中,先出现的运算符 )比刚刚得到的运算符优先数高 (在表达式中,后出现的运算符,如为减法运算符时,它们分别为 2、1),体现了先

3、来先运算的优先级规定。但乘方运算是不同的,后得到的 运算符的优先数 6 比已在栈顶的 (即:先得到的 )运算符的优先数 5 要大,因此必须先进行后得到的 乘方运算,符合乘方运算的右结合性。 开括号在输入之后, 必须马上进入到运算符栈,因为这 将意味着具有更高优先级的运算将进行,所以这时它的优先数最高为100。当它已在运算符栈内时,它的优先数被设置为 0,比其它的运算符的优先数都小。闭括号在输入时,为了保 证在当前一对开闭括号之间的运算都可以进行了,因此它的优先数为0,比乘方、加减、乘除都小。这时, 运算符栈内的所有运算符都可依次从栈中弹出,完成相应的运算。 在具体处 理时, 闭括号并不进入运算

4、符栈。 在所有运算符都从栈中弹出之后, 相应的开括号同样将从 栈中弹出, 而丢弃。 因为这一对开、 闭括号之间的表达式的值已被计算完毕,得到了一个具 体的数值,开闭括号对没有必要进行保存了。行结束符 EOL 的优先数也被设置为 0,因如 若此时运算符栈内还有运算符,它们相应的运算都可以进行了。 VALUE 是一个标志,它表 示当前得到是操作数的数值,而真正的值存放在私有成员 CurrentValue 之中的。私有成员 LastToken 用于区分得到的各种符号。在函数 GetToken 中,从字符流 Str 得 到 的各种 符号 分别被 区分 为各种 运算 符、行 结束符 EOL 以 及数 值

5、 VALUE 。函数 ProcessToken 则根据这些信息完成各种处理工作。当为运算符时,则调用函数BinaryOp 完成相应的运算。 当为 VALUE 时,则将操作数数值压入堆栈 PostFixStack。当为闭括号 CPAREN 或 EOL 时,那末就完成一对开、闭括号之间以及运算符栈中的剩余运算符相对应的运算。 函数实现的细节,大家结合各个函数的注解不难理解它们的作用。最后,必须说明的是类 Evaluator 不但可以计算类型为 int 的整数的中缀表 达式的值,同样可以计算类型为double、 float 的各种中缀表达式的值。要改动的只有计算类型为 double、 float 的

6、各种中缀表达式的计算函数,相关的部分在函数 GetValue 之中。有 兴趣的读者不妨一试。程序 2.1: 用于简单计算的计算器类 Evaluator 。# include # include # include # include “Stack.h”enum TokenEOL, V ALUE, OPAREN, CPAREN, EXP, MULT, DIV , PLUS, MINUS struct Precedence int InputSymbol;/ 刚输入的符号。int TopOfStack;/ 运算符栈的栈顶符号。 PrecTable = 0, -1, 0, 0, 100, 0, 0,

7、 99, 6, 5, 3, 4, 3, 4, 1, 2, 1, 2;/ EOL 、VALUE/ OPAREN、 CPAREN/ EXP/ MULT 、 DIV/ PLUS 、 MINUStemplate classE valuator private:Stack OpStack; / 运算符堆栈。Stack PostFixStack; / 利用后缀式完成计算操作数运算的堆栈。 istrstream Str; / 输入字符流。ElemType CurrentValue;/ 当前操作数数值。Token LastToken;/ 刚读入的各种符号, 被区分为: EOL, VALUE, OPAREN,

8、CPAREN, EXP, MULT, / DIV, PLUS, MINUS 等九种。Token GetToken( ); ElemType GetTop( ); void BinaryOp( Token );void ProcessToken( );/ 读入的各种符号送 LastToken。/ 得到堆栈 PostFixStack 的栈顶元素,即操作数数值。 / 完成运算符的相应的运算。/ 处理各种符号以及如何进行计算的函数。public:Evaluator( char * S ) : Str( S, 256 ) OpStack.Push( EOL); Evaluator ( ) ElemTyp

9、e GetValue( );/ 用于得到计算结果。;template ElemType Evaluator : GetValue( ) / 用于得到计算结果。 do LastToken = GetToken( );ProcessToken( ); while( LastToken != EOL );/ 当未得到行结束标志时,继续运算if ( PostFixStack.IsEmpty( ) ) cerr “Missing operand ! ” endl; / 栈空,错。return 0;ElemType TheResult = PostFixStack.Top( ); PostFixStack

10、.Pop( );if ( !PostFixStack.IsEmpty( ) ) / 栈非空,表示缺少运算符对操作数进行处理,错。 cerr “ Warning: Missing operators ! ” endl;return TheResult;template Token Evaluator : GetToken( ) / 读入的各种符号送 LastToken 。char Ch;while( Str.get( Ch ) & Ch = = , ? ) ; / 若为空格,则读下一字符;即跳过空格。 if ( Str.good( ) & Ch != ,n?& Ch != ,0? ) switc

11、h ( Ch ) case,?: return EXP; case,/?: return DIV ; case, *?: return MULT ; case,(?: return OPAREN ; case,)?: return CPAREN ; case,+?: return PLUS; case,-?: return MINUS; default: Str.putback(Ch); / 其它字符可能是操作数字符,所以必须写回。if ( ( Str CurrentValue ) = = 0 ) / 得到的操作数数值送 CurrentValue cerr “ Parse error! ” e

12、ndl; / 计算值,错。return EOL;return VALUE; return EOL; / 返回行结束标志。template ElemType Evaluator : GetTop( ) / 得到堆栈 PostFixStack 的栈顶元素,即操作数数值。 if ( PostFixStack.IsEmpty( ) ) cerr “Missing operand ! ” endl;return 0;ElemType Tmp = PostFixStack.Top( );PostFixStack.Pop( ); return Tmp;template void Evaluator : Bi

13、naryOp( Token TopOp ) / 完成运算符的相应的运算。if ( TopOp = = OPAREN ) cerr “Unbalanced parentheses!” endl;OpStack.Pop( ); return ;ElemType R = GetTop( );ElemType L = GetTop( );if ( TopOp = = EXP ) PostFixStack.Push( pow( L, R ) ); else if ( TopOp = = PLUS ) PostFixStack.Push( L + R );else if ( TopOp = = MINUS

14、 ) PostFixStack.Push( L - R ); else if ( TopOp = = MULT ) PostFixStack.Push( L * R );else if ( TopOp = = DIV )if ( R!= 0 )PostFixStack.Push( L / R );else cerr “Division by zero! ” endl;PostFixStack.Push( L );OpStack.Pop( );template void Evaluator : ProcessToken( )/ 处理各种符号以及如何进行计算的函数。Token TopOp;swit

15、ch ( LastToken ) case VALUE : PostFixStack.Push( CurrentValue ); return; case CPAREN: / 开闭括号之间的所有运算都可进行了。while( ( TopOp = OpStack.Top ( ) ) != OPAREN & TopOp != EOL ) BinaryOp( TopOp );if ( TopOp = = OPAREN ) OpStack.Pop( ); / 清除开括号。 else cerr “Missing opening parentheses!” endl; break;default:while

16、(PrecTableLastToken .InputSymbol=PrecTableTopOp=OpStack.Top() . TopOfStack ) BinaryOp( TopOp ); / 栈内各种高优先级的算符的运算可以进行了。if ( LastToken != EOL ) OpStack.Push( LastToken );/ 刚输入的运算符的优先级最高,则进栈。保持栈顶运算符优先级最高。 break;程序 2.2: 简单计算器的主程序。main ( ) const int LineLength = 80;char Str LineLength + 1 ; try while( cin.getline( Str, LineLength ) ) Evaluator E( Str ); cout E.GetValue( ) ,n?;catch( )cerr “Out of memory! ”en dl; exit(1); return 0;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!