四则运算——二叉树

四则运算——二叉树

题目在这:个人作业1——四则运算题目生成程序(基于控制台)

第一次作业:个人作业——四则运算

这次的程序改用了树的结构保存,优化了表达式生成方式,并完善了查重功能

程序设计基础

数据结构基础温故-4.树与二叉树(下)

从后缀表达式建立表达式树

由于从中序表达式(也就是正常的表达式)转换成树结构式在括号的处理上有点麻烦。所以将表达式转换为后序表达式再转成树结构,就可以不去处理括号。

表达式生成

根据运算符个数循环生成表达式:
每次生成一个基础数符对:`Num`+`Operator`
根据随机数判断是否生成括号与括号的位置
    1.没有括号:`原表达式`+`Num`+`Operator`
    2.括号在当前表达式后面:`原表达式`+`(`+`Num`+`Operator`,括号计数器加1
    3.括号在表达式前面:`(`+`原表达式`+`Num`+`Operator`,括号计数器加1
判断当前表达式是否存在为配对的括号
    若括号计数器不为零
    1.需要加:`原表达式`+`Num`+`)`+`Operator`,括号计数器减1
    2.不加:`原表达式`+`Num`+`Operator`
循环结束时判断括号对是否匹配完全
    若括号计数器不为零
    循环在表达式末尾加上`)`;
由于基础数符对为`Num`+`Operator`的形式,在循环结束时需要去掉末尾多余的一个Operator
    
    判断是否存在包裹整个表达式的括号,即括号对内长度是否等于表达式长度(不算括号),若存在则去除表达式两端的括号,再次判断。

二叉式生成

具体生成方式参考上面的程序设计基础,我在树的类中加上的代表运算结果的值`value`,用来存放当前树的运算结果。
    当生成节点的对象为一个`Num`的时候,节点的值就位`Num`本身。
    当对象为一个`Operator`的时候,节点的值为左右子树进行当前运算符运算后的结果,即`value Op value`
当表达式扫描完成,计算过程也就结束了,最后根节点的值就是表达式的运算结果。

查重方式

由于采用了二叉树的结构存放表达式,所以可以再二叉树生成的时候将树根据一点规则判断左右子树的对象
    若生成节点的对象是`*`或者`+`
    1.左右子树的值不同,则值大的作为左子树
    2.左右子树的值相同时,判断子树的运算符优先级大小,优先级大的作为左子树
    3.运算符优先级相同,判断子树下的左子树值得大小,值大的作为左子树
    4.若为子树为一个为数字,一个为运算符,则运算符作为左子树
    5.若左右子树都为数字,则值大的作为左子树
根据这个规则,基本上包含了交换律可能出现的情况,将可以有交换律变换得到的表达式都转为一个统一的表达式,在根据检查已生成的表达式树的结构,若存在重复的就放弃当前表达式,重新生成并查重。
在这个规则下
    3+2+1 与 3+1+2 两个表达式不是重复的表达式
因为不能再有限次的交换律加成为相同的表达式。
这个具体说明在原版的题目中

程序测试

表达式生成测试

表达式查重测试:(3+2)x(4+1) 与 (4+1)x(2+3)

原版题目:四则运算题目生成程序

代码已上传至Coding

Coding地址

https://coding.net/u/w2197525161/p/jisuan/git/tree/master/

个人想法

第一次作业由于都是自己从无到有写出来的,没有参考已有的好的思路与方法,所以时间花费较多。并且在查重方面没有很好的处理。
这次的程序是在老师建议下采用了二叉树的结构存放表达式用来解决表达式查重问题,认识到了参考的作用。很多难点已经有了各种解决方式,通过收集与整理,加上自己的理解可以更好的完成现有的任务。
优化的表达式生成方式也是在看了别人的思路下想到的。

附:

别人的思路:小学生终结者——四则运算生成器

posted @ 2017-09-24 10:48  孤舟一游客  阅读(1898)  评论(1编辑  收藏  举报