四则运算表达式生成
软件工程大作业的结对项目–四则运算题目生成器
讲述的是前两个阶段的需求分析,设计和实现
概要设计和详细设计
类的选择
有三个类,分别是存储运算符和运算数节点的二叉树类 BiTree,生成四则运算表达式的类 QuestGenerator和计算表达式结果的类solvable。QuestGenerator中的方法调用Bitree中的方法,将运算符和运算数保存在树节点中,然后生成表达式,接着调用solvable中的方法计算答案
uml图
用例图
类图
顺序图
精化类的设计
BiTree类
属性部分
有lchild rchild this_level value这四个数据结构
方法部分
分别是getOperOrder获得当前符号优先级 set_lchild设置左子树 set_rchild设置右子树 to_string将表达式转换为一字符串
QuestGenerator类
属性部分
有output_list和deduplicate_set这两个数据结构
方法部分
generate方法构建一棵二叉树
其中调用了solvable类的方法solve求解表达式
deduplicate方法给表达式判重
format方法交换左右子树
change_pow方法转换乘方符号
round_up方法对结果进行四舍五入
solvable类
属性部分,是prior这个数据结构
方法部分,calculator方法转换成逆波兰表达式,调用solve方法分步求解
实现
首先生成四则运算表达式,用父节点表示符号,叶子结点表示运算符,这样构成一棵二叉树可以用来表达一个完整的四则运算表达式,通过对这棵二叉树进行中序遍历,得到中序表达式。对于表达式的运算和结果输出,进行后序遍历,转化为逆波兰表达式,方便计算机进行计算
类
表达式生成:
首先随机的生成一系列树节点,父节点是运算符,叶子节点是运算数,将生成的节点保存在存储节点的二叉树类中
接下来通过一个新类从刚才生成的节点中随机选取一个运算符和两个运算数或者两个运算符或者一个运算符一个运算数生成表达式
用到的两个类如下:
存储四则表达式节点的二叉树类
class BiTree:
def getOperOrder(self, ch):
if ch in ['+', '-']:
return 0
elif ch in ['*']:
return 2
elif ch in ['/']:
return 3
elif ch == '^':
return 4
def __init__(self, node_type=0, val=0):
self.node_type = node_type
self.val = val
self.lchild = None
self.rchild = None
if self.node_type == 1:
self.val = chr(self.val)
self.this_level = self.getOperOrder(self.val)
def set_lchild(self, lchild):
self.lchild = lchild
def set_rchild(self, rchild):
self.rchild = rchild
def to_string(self, upper_level=0):
if self.node_type == 1:
if upper_level > self.this_level or upper_level == self.this_level == 3 or upper_level == self.this_level \
== 4:
return '(' + self.lchild.to_string(self.this_level) + self.val + self.rchild.to_string(
self.this_level + 1) + ')'
else:
return self.lchild.to_string(self.this_level) + self.val + self.rchild.to_string(self.this_level + 1)
if int(self.val) < 0:
return '(' + str(self.val) + ')'
return str(self.val)
生成四则运算表达式的生成类
类中定义的方法是generate deduplicate format_expression round_up change_pow_operator
generate是构建一棵二叉树
其中调用了solvable类的方法solve对生成的表达式求解
deduplicate是判断生成的表达式中是否有重复的(包括满足交换律的运算符左右子树交换后重复的情况)
format用于交换左右子树
change_pow表示是否需要更改表达式的乘方符号
round_up是对计算结果进行四舍五入
class QuestGenerator:
def __init__(self):
self.output_list = []
self.deduplicate_set = set()
def generate(self