C++实现任意表达式求值(栈)

今天花了大概四个小时时间,用栈(stack)实现了任意表达式的值计算的问题。

 

C++ 比 C 好的一点就是,C++ 的STL定义了大量的数据类型和算法,相比于 C 更加视觉化。

 

实现这个的基本思路很简单:分成两部分完成。两个主要函数:

    string shorten(string m) 把 string m 由中缀式变为右缀式,double calculate(string s) 计算右缀式的表达式值。

数字写入右缀式m很简单,不过别忘了用个符号把数字分开。我选择的是$。

比较难的地方是shorten函数,分析怎样把 string m 变为右缀式。可能的计算有这么几种:+,-,*,/,()。于是我通过列表的方式来分析:

    +|- *|/ (  

+|- m+=c    m+=c    push    push

*|/ push    m+=c    push    push

(   push    push    push    push

)   m+=c    m+=c    m+=c    XXXX    (XXXX表示不可能发生的情况)

竖行是操作符,横行是对应每一个竖行可能遇到的情况,代表栈为空。push表示入栈,m+=c表示元素出栈,写入表达式(右缀式)m。

其实列表的原则挺简单的:

    1. 把(看做开辟一次新的栈(从(开始算,忽视之前的元素,直到被取消);

    2. 元素a遇到相同或更高优先级的,栈顶元素c出栈,给右缀表达式m;再次对比;直到遇到更高优先级的,元素a入栈;

    3. 出现的时候,之前所有元素依次出栈,写入m,直到

    4. 在数字都加入右缀表达式之后,栈中所有元素依次出栈,写入m,直到栈为空。

关键就是 2、3条,我花了好久才总结出来的规律。顺便说下,列表法真的是很好的分析问题的方式,不重不漏还简练。

 

然后进行右缀表达式的计算,这个比较简单:数字依次入栈,遇到操作符后对栈顶的两个元素进行顺序操作(倒数第二个 +-*/ 倒数第一个),然后把这两个元素换成新的结果。如此循环即可。

 

原题目要求用int即可,但用int必然会造成除法的不精确。所以考虑用double类型,并且在读取的时候可以支持小数点。记得是有直接转化的函数,但忘了,所以自己写啦,命名为 str2double(string s)。有个dec变量决定计算整数部分还是小数部分,详细可参见函数。

 

这次实践这个程序还有个小收获,是在我无数次的debug之中:可以在某些关键步骤(比较容易发现bug的地方)加上输出语句,这样可以判断程序是否运行过了这些关键地方。

还有,顺便提一下,模块化的思想真的很重要,不然在进行一些小改动时,那种牵一发而动全身的感觉很焦虑、很凌乱。

  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值