• 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

  • 相关阅读:
    《人月神话》读后感*part1
    《程序员修炼之道——从小工到专家》阅读笔记*part6
    Java课06
    《程序员修炼之道——从小工到专家》阅读笔记*part5
    《程序员修炼之道——从小工到专家》阅读笔记*part4
    Java课堂测试——输出单个文件中的前N个最常出现的英语单词
    四则运算自动出题系统——网页版
    关于JAVA项目中的常用的异常处理情况
    《程序员修炼之道——从小工到专家》阅读笔记*part3
    《程序员修炼之道——从小工到专家》阅读笔记*part2
  • 原文地址:https://www.cnblogs.com/liuxp775/p/11569935.html
Copyright © 2020-2023  润新知