软工作业——四则运算生成器(scala 实现)
项目成员:刘跃群(3116005189)、张凯亮(3116005205)
项目仓库:https://github.com/wean2016/Myapp
PSP2.1表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 45 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 45 |
Development | 开发 | 1420 | 1985 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 200 |
· Design Spec | · 生成设计文档 | 20 | 20 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 100 | 100 |
· Design | · 具体设计 | 50 | 55 |
· Coding | · 具体编码 | 1000 | 1400 |
· Code Review | · 代码复审 | 100 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 20 | 30 |
Reporting | 报告 | 80 | 130 |
· Test Report | · 测试报告 | 30 | 32 |
· Size Measurement | · 计算工作量 | 20 | 21 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 77 |
合计 | 1560 | 2260 |
设计实现过程及代码说明
1. 生成表达式树
*** 构造表达式* @param symbolSum 剩余符号数* @param bound 表达式钟的数字不大于 bound* @return 生成的节点树的根*/def createNodeTree(symbolSum:Int, bound:Int):Node = {if (symbolSum == 0){// 中间节点构造完成,生成叶子节点Node(Number.randomNumber(bound), null, null, 0, null)}else {val left = Random.nextInt(symbolSum)val right = symbolSum - left - 1var leftNode = createNodeTree(left,bound)var rightNode = createNodeTree(right,bound)// 本节点的符号var symbol = Symbol.values()(Random.nextInt(Symbol.values().length))// 如果是除号且右节点是 0 ,那么重新生成一个不是除号的符号if (symbol == Symbol.DIV && rightNode.value.a == 0){while (symbol == Symbol.DIV){symbol = Symbol.values()(Random.nextInt(Symbol.values().length))}}// 本节点的结果var value = Calculate.calc(leftNode.value,rightNode.value,symbol).getif (Number.isNeg(value)) {// 如果运算结果是负数,交换左右节点,并把结果取绝对值value = Number.abs(value)val tempNode = leftNodeleftNode = rightNoderightNode = tempNode}val high = math.max(leftNode.high, rightNode.high) + 1// 生成本节点Node(value,leftNode,rightNode,high,symbol)}}
2. 表达式树比较去重
override def equals(obj: Any): Boolean =obj match {case that: Node =>if (that.symbol == null) {if (symbol == null ) value.equals(that.value) else false}else if (symbol == null) falseelse if (left.equals(that.left) && right.equals(that.right) && symbol==that.symbol) trueelse if ((symbol==Symbol.ADD || symbol==Symbol.MULT) && left.equals(that.right) && right.equals(that.left)) trueelse falsecase _ => false}override def hashCode(): Int = {var result = value.hashCode()result = 31 * result + (if(left == null) 0 else left.hashCode())result = 31 * result + (if(right == null) 0 else right.hashCode())result = 31 * result + (if(symbol == null) 0 else symbol.hashCode())result}
3. 打印表达式
def printNode(node: Node):String = {if (node == null) return ""val midValue = if (node.symbol == null) node.value.toString else node.symbol.value// 左右的原始值var leftValue = printNode(node.left)var rightValue = printNode(node.right)// 判断是否要加括号,如果要,就加上去if (node.symbol != null && (node.symbol == Symbol.MULT || node.symbol == Symbol.DIV)){val leftSymbol = node.left.symbolval rightSymbol = node.right.symbolif (leftSymbol != null && (leftSymbol == Symbol.ADD || leftSymbol == Symbol.SUB)) leftValue = Bracket.leftBracket.value + leftValue + Bracket.rightBracket.valueif (rightSymbol != null && (rightSymbol == Symbol.ADD || rightSymbol == Symbol.SUB)) rightValue = Bracket.leftBracket.value + rightValue + Bracket.rightBracket.value}leftValue + midValue + rightValue}
4. 从字符串生成表达式树(用于计算成绩时构造表达式树)
def fromString(s:String): Node = {// 克隆输入的字符串,实现函数式编程var value = new String(s.toCharArray)// 给符号都加上空格Symbol.values().foreach(symbol => {if (symbol.value.equals("+")){value = value.replaceAll("\\+", " %s ".format(symbol.value))}else{value = value.replaceAll(symbol.value, " %s ".format(symbol.value))}})// 给括号都加上空格Bracket.values().foreach(bracket => value = value.replaceAll("\\" + bracket.value, " %s ".format(bracket.value)))//去空格生成元素数组val factor = value.split(" ").toStream.map(s => s.trim).filter(s => !s.isEmpty).toListval nodeStack: util.Stack[Node] = new util.Stack[Node]val symbolStack: util.Stack[String] = new util.Stack[String]for (f <- factor) {// 尝试转换成数字val value = Number.fromString(f)if (value.isDefined) {// 是数字nodeStack.push(Node(value.get, null, null, 0, null))} else {// 是符号var signal = truewhile (!symbolStack.empty() && !f.equals(Bracket.leftBracket.value) && !((f.equals(Symbol.MULT.value) || f.equals(Symbol.DIV.value)) && (symbolStack.peek().equals(Symbol.ADD.value) || symbolStack.peek().equals(Symbol.SUB.value))) && !(!f.equals(Bracket.rightBracket.value) && symbolStack.peek().equals(Bracket.leftBracket.value)) && signal) {val symbol = symbolStack.pop()if (symbol.equals(Bracket.leftBracket.value) && f.equals(Bracket.rightBracket.value)) {signal = false} else {val rightNode = nodeStack.pop()val leftNode = nodeStack.pop()val sym = symbol match {case "+" => Symbol.ADDcase "-" => Symbol.SUBcase "×" => Symbol.MULTcase "÷" => Symbol.DIVcase _ => sys.error("非法运算符!")}val result = Calculate.calc(leftNode.value, rightNode.value, sym)if (result.isEmpty) {sys.error("存在不符合规范的算术表达式!")}val high = math.max(leftNode.high, rightNode.high) + 1nodeStack.push(Node(result.get, leftNode, rightNode, high, sym))}}if (!f.equals(Bracket.rightBracket.value)) {symbolStack.push(f)}}}while(!symbolStack.isEmpty){val symbol = symbolStack.pop()if (!symbol.equals(Bracket.leftBracket.value)){val rightNode = nodeStack.pop()val leftNode = nodeStack.pop()val sym = symbol match {case "+" => Symbol.ADDcase "-" => Symbol.SUBcase "×" => Symbol.MULTcase "÷" => Symbol.DIVcase _ => sys.error("非法运算符!")}val result = Calculate.calc(leftNode.value, rightNode.value, sym)if (result.isEmpty) {sys.error("存在不符合规范的算术表达式!")}val high = math.max(leftNode.high, rightNode.high) + 1nodeStack.push(Node(result.get, leftNode, rightNode, high, sym))}}nodeStack.pop()}
测试运行
生成问题
生成答案
生成成绩
把一些题目的答案改成错误
项目小结
通过结对编程,两个人互相修改代码,共同提高了能力,也写出了更好的代码。确实是种不错的写代码方式
转载于:https://www.cnblogs.com/wean2016/p/9710936.html
软工作业——四则运算生成器(scala 实现)相关推荐
- 软工作业 5:词频统计——增强功能
一.基本信息 1.1 编译环境.项目名称.作者 1 #编译环境:python3.6 2 #项目名称:软工作业5-词频统计-增强功能 3 #作者:1613072055 潘博 4 # 1613072056 ...
- 第三次软工作业——实现最大字段和算法并进行判定条件覆盖
第三次软工作业 实现最大子段和的算法并进行条件组合覆盖测试 (一)什么是最大子段和? 我自己的理解: 一个数组可以若干个子数组,包含自身.每一个字数组都有一个数组元素之和,求这些和之间的最大值. 最朴 ...
- 第一次软工作业展示——潘学
第一次软工作业完成啦! 回首这个作业的完成过程,我是很有收获.这个作业有几个难点:1.在给定目录下读取TXT文件的内容:2.从读到的内容中分析出单词:3.统计单词的出现频率并输出. 我之前只学习过C和 ...
- 第一次软工作业(构建之法)
第一次软工作业(构建之法) 关于构建之法的若干个问题 1.第一章32页,原文:"有人认为,"中文编程",是解决程序员编程效率的一个秘密武器,请问它是一个"银弹& ...
- 第一次软工作业(数独)
第一次软工作业(数独) 1.该项目的github地址: https://github.com/514DNA/sudoku 2.各个模块耗费的时间: PSP2.1 Personal Software P ...
- 2019/3/14 软工作业
自我介绍 2017xxxxx1066:我是骆树仁:我的爱好是揉白泽球: 我的码云个人主页是:https://gitee.com/sturdast/events 我的第一个项目地址是:https://g ...
- 【软工作业思考】关于软工的一些概念性理解暨第一次阅读作业
概述 项目 内容 本次作业所属课程 2019BUAA软件工程 周二班 本次作业要求 第1次个人作业 当然,比这个更重要百倍的还是实实在在的思考,这也是标题如此命名的原因 我在本课程的目标 在原有实践经 ...
- 软工作业阅读计算机前辈的随笔有感
荣誉是时间的女儿. -- 阿兰. --记第一次随笔有感. 我为什么选择计算机? 一直到高考志愿报考前,我都没认真去思考过我未来的职业,我甚至都没有构想过我的未来,在我的印象中,我应该就考上个大学,毕业 ...
- 软工作业No.3--团队作业:甜美女孩出击!
队名:甜美女孩 队员包括: 姓名 学号 身份 曾祎祺 3216005211 队长 邓画月 3216005212 队员 何颖琪 3216005213 队员 梁沛诗 3216005214 队员 梁子君 3 ...
最新文章
- 最大子矩阵(降维处理)
- pyqt5教程13:客户定制组件
- 分类模型的评估方法-精确率(Precision)
- Springboot学习问题记录
- Java Socke 探究
- salesforce 架构设计_关于Salesforce证书维护重要通知
- 怎么安装python2.7_python2.7环境如何安装
- 末日前的唠叨:SEO之四大要不得
- linux awk使用详解
- HEX文件和BIN文件格式的区别
- Linux源码编译即黑客帝国屏保cmatrix安装
- MATLAB - 傅里叶分析及 FFT 频谱分析
- 分享添加字幕最简单的方法 视频制作超简单
- 性能优化检测Instruments-time profile的使用
- 非递归前序遍历二叉树,非递归中序遍历二叉树,非递归后续遍历二叉树
- 【VBA编程】VBA基础语法(二)
- 算法-时间复杂度和空间复杂度
- idea几款好用的插件
- 小白自学CAD教程:706集全网最新CAD学习教程,一学就会
- 什么是DDX,DDY,DDZ?
热门文章
- Linux内核参数调优
- 如何有效地防止网站和手机APP的数据被采集?
- mysql 常用操作命令
- Eclipse常用设置
- 经典DP 嵌套矩形 (南洋理工ACM—16)
- Exchange Server 2010安装测试
- 关于一个CCIE考试题目的研究(重分发)
- c语言修仙角色,C语言修仙手游-C语言修仙手游安卓版V7.4.0预约_第一手游网
- android 绑定端口号,android 获取IP端口号等地址
- Python3 AttributeError: module 'cv2' has no attribute 'SIFT'