项目地址:https://git.coding.net/meiyoupiqidefan/Four-Operations.git
目录:
一、需求分析
二、功能设计
三、设计实现
四、算法详解
五、测试运行
六、粘贴代码
七、总结
八、展示PSP
————————————————————————————
一、需求分析
由于每次出题的数目不定,所以要求题数参数n由控制台输入
小学生水平有限,故每个数字在 0 和 100 之间,运算符在3个到5个之间。
为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,所出的练习题在运算过程中不得出现负数与非整数。
————————————————————————————
二、功能设计
基本功能:
实现3~5个运算符的,两位数以内的,不含小数点的加减乘除四则运算
扩展功能:
支持有括号的运算式
扩展程序功能支持真分数加减法的出题与运算
支持运算时分数的自动化简
————————————————————————————
三、设计实现
设计包括你会有哪些类,这些类分别负责什么功能,他们之间的关系怎样?你会设计哪些重要的函数,关键的函数是否需要画出流程图?函数之间的逻辑关系如何?
一个类,Main类,实现基本功能的所有要求
Main类下有3个函数:main,evaluateExpression,processOneOperator
main: 生成四则运算式子
evaluateExpression:计算后缀表达式
processOneOperator:对操作符栈顶的一个操作符进行计算
————————————————————————————
四、算法详解
请描述你生成题目与解答题目用到的算法,并说明在求解题目时你是如何使用调度场算法 或其他算法来处理不同运算符的优先级的?
利用了栈,调度场算法等
调度场算法思想:
从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,优先级不高于栈顶符号则栈顶元素一次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
逆波兰表达式求值:
从左到右遍历后缀表达式的每个数字和字符,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈进行运算,运算结果进栈,一直到最终获得结果。
一个栈存放数字,一个栈存放操作符
————————————————————————————
五、测试运行
你的程序必须是可运行的,请展示程序的运行截图,包括题目要求实现功能对应的运行截图。这些截图说明你的程序确实完成了项目需求,如果程序实现了扩展需求,也请大方秀出来。
————————————————————————————
六、粘贴代码
粘贴自己觉得比较独特的或满意的代码片段,用博客园正确的代码控件来显示。(提示:要有必要的注释说明,提示:不要贴所有代码!不符合规定的要倒扣分)
1 //生成算术式 2 int size = list.size(); 3 String[] array = (String[]) list.toArray(new String[size]); 4 5 Random random = new Random(); 6 String str =""; 7 int[] number=new int[6]; 8 boolean flag2 = true; 9 while (flag2) { 10 int[] index = null; 11 int op_number = random.nextInt(3) + 3; // 3-5个运算符,运算符个数 12 index = new int[op_number]; 13 for (int j = 0; j < op_number; j++){ 14 index[j] = random.nextInt(4); 15 number[j] = random.nextInt(100); 16 str += number[j]+array[index[j]]; 17 } 18 // 随机选择运算符 19 for (int j = 1; j < op_number; j++) { 20 if (index[0] != index[j]) 21 flag2 = false; 22 } 23 str=str+random.nextInt(100); 24 }
// 后缀表达式 for (int i = 0; i < result.size(); i++) { if (result.get(i).equals("+") || result.get(i).equals("-")) { // 若字符串为"+"或者"-",则执行栈中已存数据的加减乘除计算 while (!operatorStack.isEmpty() && (operatorStack.peek() == ‘+‘ || operatorStack.peek() == ‘-‘ || operatorStack.peek() == ‘*‘ || operatorStack .peek() == ‘/‘)) { processOneOperator(operandStack, operatorStack); } operatorStack.push(result.get(i).charAt(0));// 将操作符压入操作符栈中 } else if (result.get(i).equals("*") || result.get(i).equals("/")) { // 若字符串为"*"或者"/",则执行栈中已存数据的乘除计算 while (!operatorStack.isEmpty() && (operatorStack.peek() == ‘*‘ || operatorStack.peek() == ‘/‘)) { processOneOperator(operandStack, operatorStack); } operatorStack.push(result.get(i).charAt(0)); } else { // 若遇到的是操作数,则将操作数直接压入操作数栈中 operandStack.push(Integer.parseInt(result.get(i))); } } // 对栈中数据进行计算,直到栈为空为止 while (!operatorStack.isEmpty()) { processOneOperator(operandStack, operatorStack); } // 此时操作数栈中的栈顶元素也就是计算结果 return operandStack.pop(); }
————————————————————————————
七、总结
你设计的程序如何实现软件设计的‘模块化‘原则。
模块化:模块化是以分治法为依据。简单说就是把软件整体划分,划分后的块组成了软件。这些块都相对独立,之间用接口(协议)通信,每个块完成一个功能,多个块组合可以完成一系列功能。
模块化目的:降低软件的复杂性,提高工作效率,提高软件质量
我的模块化:将功能分为3个函数,main函数用于生成四则运算式子;evaluateExpression函数用于计算后缀表达式;processOneOperator用于对操作符栈顶的一个操作符进行计算。再通过main函数调用evaluateExpression函数,evaluateExpression函数规定优先级,分解成简单的两个数字,一个操作符的运算,以实现全部的计算功能。
————————————————————————————
八、展示PSP
这个环节重要的是让自己看到自己的估计和实际消耗时间,哪个环节耗时最多,哪个环节估计和实践相差巨大?为什么?
PSP |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
10 |
12 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
5 |
10 |
Development |
开发 |
5*60 |
3*60 |
Analysis |
需求分析 (包括学习新技术) |
10*60 |
8*60 |
Design Spec |
生成设计文档 |
30 |
50 |
Design Review |
设计复审 (和同事审核设计文档) |
20 |
1*60 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
Design |
具体设计 |
30 |
45 |
Coding |
具体编码 |
10*60 |
10*60 |
Code Review |
代码复审 |
30 |
40 |
Test |
测试(自我测试,修改代码,提交修改) |
2*60 |
1*60 |
Reporting |
报告 |
2*60 |
60 |
Test Report |
测试报告 |
1*60 |
30 |
Size Measurement |
计算工作量 |
20 |
20 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
30 |
20 |
在技术学习和具体编码环节花费时间比较多,我在一开始设计思路的时候,有一些具体的函数不会使用,也学习了调度场算法,从吸收到掌握花费了比较多的时间,在具体的编码上也是一边写一边改,所以也不好说一些具体的时间分配是什么样的。但是大体上说,估计用的时间和实际使用的情况差不多,我想,课本上的psp相关内容和老师推荐博客给予了很大帮助。
这次的任务,花费了不少时间,只有去实践才能进步,查缺补漏,锻炼自我。