20190919-6 四则运算试题生成,结对

本次作业要求参见:[https://edu.cnblogs.com/campus/nenu/2019fall/homework/7631]

 

结对伙伴:韩昊

 

• 功能1. 四则运算
支持出题4个数的四则运算题目,所有题目要求作者有能力正确回答

重难点:四个数字的四则运算,分两种优先级,加减与乘除,因此在计算表达式的时候,不能顺序处理。不过我想到了编译原理中,对于表达式的处理原理,因此借助了栈结构及逆波兰式的转换。

编程收获:本功能表面看起来简单,于是抬手就做,可是在实施时遇到了事先没有考虑到的问题,所以此处得出教训,在处理任何问题之前,需要多花些时间,进行详细的功能分析和设计,此处想到了一句话:“有的时候慢一点,往往会更快一点”。

重点代码片段

# 将中缀表达式转换为后缀表达式
def middle_to_after(s):
    expression = []
    ops = []
    for item in s:
        if item in ['+', '-', '*', '/']:
            while len(ops) >= 0:
                if len(ops) == 0:
                    ops.append(item)
                    break
                op = ops.pop()
                if op == '(' or op_rules[item] > op_rules[op]:
                    ops.append(op)
                    ops.append(item)
                    break
                else:
                    expression.append(op)
        elif item == '(':
            ops.append(item)
        elif item == ')':
            while len(ops) > 0:
                op = ops.pop()
                if op == '(':
                    break
                else:
                    expression.append(op)
        else:
            expression.append(item)

    while len(ops) > 0:
        expression.append(ops.pop())

    return expression
# 计算后缀表达式
def cal_suffix_exp_value(expression):
    stack_value = []
    for item in expression:
        if item in ['+', '-', '*', '/']:
            n2 = stack_value.pop()
            n1 = stack_value.pop()
            result = cal_rules(n1, n2, item)
            stack_value.append(result)
        else:
            stack_value.append(int(item))
    return stack_value[0]

 

 

• 功能2. 支持括号

重难点:此功能在功能1的基础上,增加了括号,思路上还是借助逆波兰式,但有个问题是如何保证随机生成的一对括号有意义,因此这里并不是真正意义上的随机,而是一种伪随机。

编程收获:这个地方的随机机制花费了很长时间去思考,最终伪随机借鉴了某些小游戏中的随机机制,所以收获是,平时还要多拓展自己的解决问题的思路,这样在考虑问题时才会更开阔。

重点代码片段:

# 4个数的式子括号最多两对,随机生成一对括号或两对括号
position_matrix = [[-1, 0, 0, 0, 1, 0, 0, 0, 0, 2, 2],
                   [-1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2],
                   [0, 0, -1, 0, 0, 0, 1, 0, 0, 2, 2],
                   [0, 0, -1, 0, 0, 0, 0, 0, 1, 2, 2],
                   [0, 0, 0, 0, -1, 0, 0, 0, 1, 2, 2],
                   [-1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1],
                   [-1, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0],
                   [-1, 0, 0, -1, 0, 0, 0, 1, 1, 0, 0],
                   [0, 0, -1, -1, 0, 0, 0, 1, 0, 0, 1],
                   [0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 1]
                   ]

# 生成括号表达式
def generate_parentheses(self, exp):
    expression = []

    # 从10种情况中选取一种
    position = random.randint(0, 9)

    if exp:
        i = 0
        for j in self.position_matrix[position]:
            if j == 0:
                expression.append(exp[i])
                if i < len(exp):
                    i += 1
            elif j == -1:
                expression.append('(')
            elif j == 1:
                expression.append(')')


    # 如果生成的括号表达式形如 (1 + 2/3 + 3) 则重新生成 (1+(2+3))+4  1+((2+3)+4) 1+(2+(3+4))
    if expression[0] == '(' and expression[-1] == ')':
        expression = self.generate_parentheses(exp)
        return expression
    return expression

 

[注]在实际代码中,我们将功能1和功能2结合到了一起,因此最终实现起来的结果是这样的:

 

 

• 功能3. 限定题目数量,"精美"打印输出,避免重复

重难点:在前两个功能前提下,实现功能3相对来说比较简单,相对来说,重点是保证按参数指定的个数输出表达式及结果。编程收获:。

重点代码片段:

# 功能三输出一行计算表达式及结果
def print_exp_result(num):
    i = 0
    num = int(num)
    while i < num:
        generate = Exp_Generator.Generator()
        mid_experision = generate.generate()
        suffix_expression = middle_to_after(mid_experision)
        value = cal_suffix_exp_value(suffix_expression)
        mid_experision += '='
        print('%-15s %-15s' % (mid_experision, value))
        i += 1

 

 

• 总结与体会

1、费时

1.1 关于栈在四则运算的使用

由于对本科学习的数据结构内容有所遗忘,导致在该部分花费了一定时间,通过查阅教材,教程等等,由于逆波兰和栈的使用是重点所以遇到困难我们仍然坚持使用,最后慢慢摸索,实现了该功能。

1.2 研究如何避免生成重复问题
解决的办法在前文的文字和代码中已经有所体现,但在该部分确实花费了较多时间,我们通过积极思考,积极交流,最终找出当下的办法。

2、收获

2.1 关于结对编程:沟通太重要了,分工太重要了,真的要坐在一起编码,有问题随时交流,这样才能将两个人的能量最大化。

2.2 关于费时问题处理:每个人对某项问题的看法和理解都不一样,在处理费时问题时,两个人各抒己见,解决问题的思路也拓宽了,毕竟一个人的想法还是比较宅,以后再遇到比较难的费时问题时,还需要多跟别人交流,问题会变得简单。

3、给出照片1张,包括结对的2位同学、工作地点、计算机,可选项包括其他能表达结对编程工作经历的物品或场景。

工作地点:冬华B 620寝室

使用本人的电脑进行编程

 

 

• 版本控制

代码Git地址:https://e.coding.net/secret/ASETest1_3.git

posted @ 2019-09-22 23:18  刘信鹏  阅读(244)  评论(1编辑  收藏  举报