项目成员:刘跃群(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 实现)相关推荐

  1. 软工作业 5:词频统计——增强功能

    一.基本信息 1.1 编译环境.项目名称.作者 1 #编译环境:python3.6 2 #项目名称:软工作业5-词频统计-增强功能 3 #作者:1613072055 潘博 4 # 1613072056 ...

  2. 第三次软工作业——实现最大字段和算法并进行判定条件覆盖

    第三次软工作业 实现最大子段和的算法并进行条件组合覆盖测试 (一)什么是最大子段和? 我自己的理解: 一个数组可以若干个子数组,包含自身.每一个字数组都有一个数组元素之和,求这些和之间的最大值. 最朴 ...

  3. 第一次软工作业展示——潘学

    第一次软工作业完成啦! 回首这个作业的完成过程,我是很有收获.这个作业有几个难点:1.在给定目录下读取TXT文件的内容:2.从读到的内容中分析出单词:3.统计单词的出现频率并输出. 我之前只学习过C和 ...

  4. 第一次软工作业(构建之法)

    第一次软工作业(构建之法) 关于构建之法的若干个问题 1.第一章32页,原文:"有人认为,"中文编程",是解决程序员编程效率的一个秘密武器,请问它是一个"银弹& ...

  5. 第一次软工作业(数独)

    第一次软工作业(数独) 1.该项目的github地址: https://github.com/514DNA/sudoku 2.各个模块耗费的时间: PSP2.1 Personal Software P ...

  6. 2019/3/14 软工作业

    自我介绍 2017xxxxx1066:我是骆树仁:我的爱好是揉白泽球: 我的码云个人主页是:https://gitee.com/sturdast/events 我的第一个项目地址是:https://g ...

  7. 【软工作业思考】关于软工的一些概念性理解暨第一次阅读作业

    概述 项目 内容 本次作业所属课程 2019BUAA软件工程 周二班 本次作业要求 第1次个人作业 当然,比这个更重要百倍的还是实实在在的思考,这也是标题如此命名的原因 我在本课程的目标 在原有实践经 ...

  8. 软工作业阅读计算机前辈的随笔有感

    荣誉是时间的女儿. -- 阿兰. --记第一次随笔有感. 我为什么选择计算机? 一直到高考志愿报考前,我都没认真去思考过我未来的职业,我甚至都没有构想过我的未来,在我的印象中,我应该就考上个大学,毕业 ...

  9. 软工作业No.3--团队作业:甜美女孩出击!

    队名:甜美女孩 队员包括: 姓名 学号 身份 曾祎祺 3216005211 队长 邓画月 3216005212 队员 何颖琪 3216005213 队员 梁沛诗 3216005214 队员 梁子君 3 ...

最新文章

  1. 最大子矩阵(降维处理)
  2. pyqt5教程13:客户定制组件
  3. 分类模型的评估方法-精确率(Precision)
  4. Springboot学习问题记录
  5. Java Socke 探究
  6. salesforce 架构设计_关于Salesforce证书维护重要通知
  7. 怎么安装python2.7_python2.7环境如何安装
  8. 末日前的唠叨:SEO之四大要不得
  9. linux awk使用详解
  10. HEX文件和BIN文件格式的区别
  11. Linux源码编译即黑客帝国屏保cmatrix安装
  12. MATLAB - 傅里叶分析及 FFT 频谱分析
  13. 分享添加字幕最简单的方法 视频制作超简单
  14. 性能优化检测Instruments-time profile的使用
  15. 非递归前序遍历二叉树,非递归中序遍历二叉树,非递归后续遍历二叉树
  16. 【VBA编程】VBA基础语法(二)
  17. 算法-时间复杂度和空间复杂度
  18. idea几款好用的插件
  19. 小白自学CAD教程:706集全网最新CAD学习教程,一学就会
  20. 什么是DDX,DDY,DDZ?

热门文章

  1. Linux内核参数调优
  2. 如何有效地防止网站和手机APP的数据被采集?
  3. mysql 常用操作命令
  4. Eclipse常用设置
  5. 经典DP 嵌套矩形 (南洋理工ACM—16)
  6. Exchange Server 2010安装测试
  7. 关于一个CCIE考试题目的研究(重分发)
  8. c语言修仙角色,C语言修仙手游-C语言修仙手游安卓版V7.4.0预约_第一手游网
  9. android 绑定端口号,android 获取IP端口号等地址
  10. Python3 AttributeError: module 'cv2' has no attribute 'SIFT'