题目
(1)能自动生成小学四则运算题目;
(2)能支持任意分数的四则运算;
(3)能支持任意括号运算
思路
根据参数生成不定长度的表达式,以及能控制是否生成分数,能生成任意数量的中缀表达式,支持四则运算,括号运算以及分数运算
构造函数接口 def __init__(self, exps_num=10, num_l=1, num_r=10, exp_limit_len=10, has_fraction=True)
提供接口生成中缀表达式,返回表达式数据集 def create_express(self)
提供接口将中缀表达式化为后缀表达式 def get_postfix(self, exp)
提供接口将后缀表达式进行计算并返回结果 def cal_express(self, exp)
提供接口以用户友好方式显示中缀表达式 def get_showExp(self, exp)
源代码
# -*- coding: utf-8 -*-# author: ‘boliang‘# date: 2018/4/18 21:04 import profileimport randomfrom fractions import Fraction class Solution(object): def __init__(self, exps_num=10, num_l=1, num_r=10, exp_limit_len=10, has_fraction=True): self.__exps_num = exps_num self.__has_fraction = has_fraction self.__exp_limit_len = exp_limit_len self.__num_l = num_l self.__num_r = num_r # 生成中缀表达式 def create_express(self): exps = [] num = self.__exps_num while num > 0: num_len = random.randint(2, self.__exp_limit_len) tmp_len = num_len - 1 exp = [self.__get_num(self.__has_fraction)] while tmp_len > 0: # 1为+,2为-,3为*,4为/ op_flag = random.randint(1, 4) if op_flag == 1: exp.append(‘+‘) elif op_flag == 2: exp.append(‘-‘) elif op_flag == 3: exp.append(‘*‘) else: exp.append(‘/‘) exp.append(self.__get_num(self.__has_fraction)) tmp_len -= 1 brackets = random.randint(0, int(len(exp)/8)) while brackets > 0: if self.__set_bracket(exp, num_len): brackets -= 1 exps.append(exp) num -= 1 return exps def __set_bracket(self, exp, num_len): index_a = 0 index_b = 0 while index_a == index_b: rec = list(map(lambda x:random.randint(0, num_len-1), range(2))) index_a = min(rec) + 1 index_b = max(rec) + 1 cal = 0 length = len(exp) for i in range(length): if type(exp[i]) != type(‘+‘): cal += 1 if cal == index_a: if i+1 <= length and exp[i+1] == ‘)‘: return False exp.insert(i, ‘(‘) cal = 0 for i in range(len(exp)): if type(exp[i]) != type(‘+‘): cal += 1 if cal == index_b: if i-1 >= 0 and exp[i-1] == ‘(‘: return False exp.insert(i+1, ‘)‘) break return True # 生成一个数, 包括分数 def __get_num(self, has_fraction=True): # 生成包括有分数 if has_fraction: # 80%几率为整数 flag = random.randint(1, 10) if flag <= 8: return self.__get_num(False) else: return Fraction(self.__get_num(False), self.__get_num(False)) # 生成整数 else: return random.randint(self.__num_l, self.__num_r) # 计算后缀表达式 def cal_express(self, exp): record = [] for val in exp: if type(val) == type(‘+‘): b = record.pop(-1) a = record.pop(-1) if val == ‘+‘: record.append(a+b) elif val == ‘-‘: record.append(a-b) elif val == ‘*‘: record.append(a*b) else: record.append(a/b) else: record.append(val) return record[0] # 通过中缀表达式得到后缀表达式 def get_postfix(self, exp): l_ops = { ‘(‘: 1, ‘*‘: 5, ‘/‘: 5, ‘+‘: 3, ‘-‘: 3, ‘)‘: 6 } r_ops = { ‘(‘: 6, ‘*‘: 4, ‘/‘: 4, ‘+‘: 2, ‘-‘: 2, ‘)‘: 1 } op_stack = [] post_stack = [] for val in exp: if type(val) != type(‘+‘): post_stack.append(val) elif len(op_stack) > 0: while len(op_stack) > 0 and l_ops[op_stack[-1]] >= r_ops[val]: if op_stack[-1] != ‘(‘ and op_stack[-1] != ‘)‘: post_stack.append(op_stack.pop(-1)) else: op_stack.pop(-1) op_stack.append(val) else: op_stack.append(val) while len(op_stack) > 0: if op_stack[-1] != ‘(‘ and op_stack[-1] != ‘)‘: post_stack.append(op_stack.pop(-1)) else: op_stack.pop(-1) return post_stack def get_showExp(self, exp): op = {‘+‘: ‘+‘, ‘-‘: ‘-‘, ‘*‘: ‘ב, ‘/‘: ‘÷‘, ‘(‘:‘(‘, ‘)‘:‘)‘} jud_fun = lambda val: str(val) if type(val) != type(‘+‘) else op[val] return ‘ ‘.join(map(jud_fun, exp)) # 测试函数def test(): # 1. 测试程序自动生成10组表达式数据(包括分数和括号运算) # 2. 测试通过中缀表达式计算得到后缀表达式 # 3. 根据后缀表达式计算结果(包括分数) # 设置接口参数 # 表达式个数 express_num = 10 # 生成的数的下界 num_l = 1 # 生成的数的上界 num_r = 10 # 表达式的数字个数 exp_limit_len = 10 # 是否会生成分数 has_fraction = True sol = Solution(express_num, num_l, num_r, exp_limit_len, has_fraction) # 生成中缀表达式 exps = sol.create_express() for ind, exp in enumerate(exps): print(‘.......................................‘) print(‘第{0}条表达式:{1}‘.format(ind+1, exp)) tmp = sol.get_postfix(exp) print(‘后缀表达式为:{0}‘.format(tmp)) print(‘用户界面中显示的表达式:{0}‘.format(sol.get_showExp(exp))) print(‘运算结果为:{0}‘.format(sol.cal_express(tmp))) print(‘.......................................‘) if __name__ == ‘__main__‘: profile.run(‘test()‘) 根据单元测试,测试结果如下
效能分析, 运用Python profile库
PSP表格
预计耗时(分钟) | 是实际耗时(分钟) | ||
Planning | 计划 | 10 | 10 |
Estimate | 估计这个任务需要多少时间 | 100 | 100 |
Development | 开发 | 120 | 240 |
Analysis | 需求分析 | 5 | 10 |
Design Spec | 生成设计文档 | 3 | 23 |
Design Review | 设计复审(和同事审核设计文档) | 2 | 2 |
Coding Standerd | 代码规范(为目前的开发制定合适的规范) | 3 | 3 |
Design | 具体设计 | 5 | 10 |
Coding | 具体编码 | 30 | 60 |
Code Review | 代码复审 | 5 | 10 |
Text | 测试(自测,修改代码,提交修改) | 10 | 30 |
Reporting | 报告 | 10 | 20 |
Text Report | 测试报告 | 10 | 20 |
Size Measurement | 计算工作量 | 5 | 5 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 5 | 5 |
Sum | 合计 | 215 | 420 |
原文地址:https://www.cnblogs.com/lbliang/p/8878753.html
时间: 2024-11-08 16:19:56