四则运算
软件工程第三周作业 —— 四则运算
1. 项目要求
1.1 要求阐述
- 生成小学四则运算题题目,结果不能为负数
- 支持真分数的四则运算
1.2 详细要求 【易知大学】
1.3 详细代码 【GitHub】
2. PSP表格
PSP2.1
Personal Software Process Stages
预估耗时(分钟)
实际耗时(分钟)
Planning
计划
15
25
Estimate
估计这个任务需要多少时间
15
25
Development
开发
247
395
Analysis
需求分析 (包括学习新技术)
30
45
Design Spec
生成设计文档
30
30
Design Review
设计复审 (和同事审核设计文档)
15
10
Coding Standard
代码规范 (为目前的开发制定合适的规范)
12
10
Design
具体设计
30
35
Coding
具体编码
60
180
Code Review
代码复审
30
20
Test
测试(自我测试,修改代码,提交修改)
40
65
Reporting
报告
85
60
Test Report
测试报告
30
25
Size Measurement
计算工作量
30
10
Postmortem & Process Improvement Plan
事后总结, 并提出过程改进计划
25
25
合计
347
480
3. 解题思路描述
将问题分解为两部分:第一部分生成算式,第二部分计算算式的值。
3.1 第一部分
生成算式分为三个小步骤。
首先,使用随机数生成操作数与运算符,通过参数设置操作数与运算符的数量,再将其拼接为算式,如3×7+9÷3。
其次,在算式上插入括号,括号插在有乘除附近的加减子算式中,如3×(7+9)÷3。
最后,在算式的基础上将其中的数字替换为分数,如果不想使用分数则跳过此步骤。
3.2 第二部分
计算算式的值,将算式转为逆波兰式,之后使用栈计算算式结果,结果保留分数形式,如7/2。
4. 设计实现过程
4.1 参数说明
创建OPT方法存储相关参数,如操作数数值上限、操作数个数、使用的运算符种类、是否包含分数。
4.2 生成算式
使用GeneralFormular类生成算式的中缀表达式,其中包含8个方法。
方法
说明
1
def catFormula(self, operand1, operator, operand2)
连接算式
2
def getRandomIntOperand(self)
返回随机整数操作数
3
def getRandomFractionOperand(self)
返回随机分数操作数
4
def getRandomOperator(self)
返回随机运算符
5
def getOriginFormular(self)
生成整数源算式
6
def insertBracket(self, formular)
插入括号
7
def replaceFraction(self, formular)
带入分数
8
def solve(self)
整合生成算式的后缀表达式,带括号
4.3 计算算式
使用ComputeFormular类计算算式,通过将中缀表达式转为后缀表达式,使用栈计算结果。
方法
说明
1
def getPostFormular(self, formular)
中缀表达式转为后缀表达式
2
def calcFormular(self, formular)
计算算式的值
3
def solve(self, formular)
整合计算中缀表达式的值
5. 代码示例
5.1 GeneralFormular.getOriginFormular()方法
def getOriginFormular(self):"""* 生成整数源算式
* @return {str}
"""# 通过self.opt.oper_num控制操作数个数,循环调用catFormula()方法构造算式
tmp = self.getRandomIntOperand()
for i in range(self.opt.oper_num-1):
tmp = self.catFormula(tmp, self.getRandomOperator(), self.getRandomIntOperand())
# 去掉"÷0"
while(True):
if"÷0"in tmp:
tmp = tmp.replace("÷0", "÷"+str(self.getRandomIntOperand()))
else:
break
return tmp
5.2 GeneralFormular.insertBracket()方法
def insertBracket(self, formular):"""* 插入括号
* @param formular {str} 源算式
* @return {str}
"""# print(formular)
# 若只包含+号 或 只有两个操作数 则不用加括号
if self.opt.oper_variety <= 2 or self.opt.oper_num == 2:
return formular
# 若不包含×÷ 则不用加括号
if"×"notin formular and"÷"notin formular:
return formular
# 操作数列表
operand_list = re.split("[-|+|×|÷]", formular)
# 操作符列表
operator_list = re.split("[!0-9]", formular)
# 去掉空字符
while""in operator_list:
operator_list.remove("")
# print(operand_list, operator_list)
# 存储添加括号的算式
new_formular = ""
# flag表示是否已存在左括号,作用在于构造出一对括号
flag = 0
# 添加括号
for i in range(len(operator_list)):
oper = operator_list.pop(0)
# 若下一个符号为 + or - , 则插入括号
if oper == "-"or oper == "+":
if flag == 0:
new_formular += "("
flag = 1
new_formular += (str(operand_list.pop(0)) + str(oper))
else:
new_formular += str(operand_list.pop(0))
if flag == 1:
new_formular += ")"
flag = 0
new_formular += str(oper)
# print(operand_list, operator_list, new_formular)
new_formular += str(operand_list.pop(0))
if flag == 1:
new_formular += ")"
return new_formular
6. 测试运行
6.1 不包含分数
6.2 包含分数
7. 单元测试
1import unittest 2from formula import OPT, GeneralFormular, ComputeFormular 34class FormulaUnitTest(unittest.TestCase):
5def test_gf_catFormular(self):
6"""
7 * 测试拼接算式
8"""
9 gf = GeneralFormular(OPT())
10 self.assertEqual(gf.catFormula("12", "+", "34"), "12+34")
11 self.assertEqual(gf.catFormula("23", "+", "456"), "23+456")
12 self.assertEqual(gf.catFormula("1z", "+", "32"), "1z+32")
13
14def test_cf_getPostFormular(self):
15"""
16 * 测试中缀表达式转为后缀表达式
17"""
18 cf = ComputeFormular()
19 self.assertEqual(cf.getPostFormular("3+7"), "3#7#+")
20 self.assertEqual(cf.getPostFormular("3×(7+2+1)"), "3#7#2#+1#+×")
21 self.assertEqual(cf.getPostFormular("6×(2+1)÷(9-2+3)"), "6#2#1#+×9#2#-3#+÷")
22 self.assertEqual(cf.getPostFormular("6×(2+1)÷0"), "6#2#1#+×0#÷")
23
24def test_cf_calcFormular(self):
25"""
26 * 测试后缀表达式计算为数值
27"""
28 cf = ComputeFormular()
29 self.assertEqual(cf.calcFormular("3#7#+"), "10")
30 self.assertEqual(cf.calcFormular("3#7#2#+1#+×"), "30")
31 self.assertEqual(cf.calcFormular("6#2#1#+×9#2#-3#+÷"), "9/5")
32 self.assertEqual(cf.calcFormular("6#2#1#+×0#÷"), "NaN")
33
34
35if__name__ == "__main__":
36 unittest.main()
8. 性能分析
8.1 GeneralFormular.getOriginFraction()方法
8.2 GeneralFormular.replaceFraction()方法
8.3 GeneralFormular.solve()方法
8.4 ComputeFormular.solve()方法
以上是 四则运算 的全部内容, 来源链接: utcz.com/z/530285.html