我认为四则运算生成程序功能上分为两大部分,随机生成四则运算表达式+四则运算表达式的计算
开始的时候想从编程结构上划分这两部分,用逆波兰表达式和栈的结构进行四则运算的计算,但是实现效果不太理想,编程到一半就编不下去了。
后来上网查阅了一些资料,并受到《编译原理》书中表达式可以用树的结构来表示的启发,我采用了二叉树的数据结构,并采用了生成表达式和计算表达式同时进行的方法,用递归运算的思想,重新编写了这个程序。
至于生成算式的随机性,则采用了控制表达式中数字个数的方法(叶子数量),来控制表达式的长度。
采用的数据结构如下:
其中每个单元存储运算结果和运算符,叶子存储的就是运算数字。
生成运算表达式和进行计算的过程结合在一起:自顶向下生成框架,填入运算符;然后自底向上填入数字,同时计算结果。
拿一个例子进行说明:
得出的结果为:(1+2)*3/4=9/4=2‘1/4
大致的设计思路和采用的数据结构就是这样的
下面总结一下编程的时候解决的问题:
1)首先就是四则运算程序需要支持真分数的运算,为了一致性,我把整数写成了真分数的形式,用一个struct保存分母和分子。
2)分数运算时要用到最小公倍数,约分时要用到最大公约数:最小公倍数=两数之积/最大公约数
3)输出到文件的时候采用的是ofstream类型的对象,遇到了两个问题:
首先,为了提高效率和减少代码冗余,我把屏幕上的输出和到文件的输出放到一个函数里,只周游树一遍就完成了两项工作。但是输出到文件就采用了递归的方式,但是输出的顺序有时会发生混乱,我采用了ofstream::flush()的方法解决。但是感觉这样的方法还是不好,如果输出逻辑再复杂一点,这个方法也许就不再适用了。
其次,我想在输出之前清空文件,如果采用ofstream对象,只好采用先打开文件再关闭它的方法,并加上清空文件的参数。感觉这也并不是一个好的方法,有点蠢......
总之,运行效果如下图:
目前进度是这里,通过做个人项目感觉自己对数据结构和算法的掌握还是太差了,还有很长一段路要走啊(望天).......