一.代码仓库地址:https://git.coding.net/maleping/MaLePing_calculator_2016012042.git
二.需求分析
- 接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题。
- 每个数字在 0 和 100 之间,运算符在3个到5个之间。
- 每个练习题至少要包含2种运算符。
- 所出练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。
- ,将学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
三.功能设计
1.根据用户输入的参数n随机产生n道符合要求的练习题并自动显示答案
2.将产生的练习题以文档形式呈现。
四.设计实现
(1)Main.java类启动程序,接收参数n,引用CreateFile.java
(2)CreateFile.java类生成result.txt文件,引用 produceExercise.java类
(3)produceExercise.java类随机产生操作符和操作数
(4)Calculate.java类计算题目结果
五.算法详解
用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack,一个用来保存计算优先符priStack
基本算法实现思路为:用当前取得的运算符与priStack栈顶运算符比较优先级:若高于,则因为会先运算,放入栈顶;若等于,因为出现在后面,所以会后计算,所以栈顶元素出栈,取出操作数运算;若小于,则同理,取出栈顶元素运算,将结果入操作数栈。
六.测试运行
七.满意代码
题目生成部分代码(借鉴了某同学的想法)
1 public static String formula(){ 2 Random random = new Random(); 3 String[] operatorCharacter = {"+","-","*","/"}; 4 int operatorCharacterCount = random.nextInt(3)+3; //随机产生3-5个操作符 5 int[] num = new int[1+operatorCharacterCount]; 6 int[] idx = Idx(operatorCharacterCount); 7 String f = new String(); 8 for(int i=0;i<operatorCharacterCount+1;i++){ 9 num[i] = random.nextInt(101); //随机产生0-100的操作数 10 } 11 if(operatorCharacterCount==3){ 12 f=num[0]+operatorCharacter[idx[0]]+num[1]+operatorCharacter[idx[1]]+num[2]+operatorCharacter[idx[2]]; 13 } 14 else if(operatorCharacterCount==4){ 15 f=num[0]+operatorCharacter[idx[0]]+num[1]+operatorCharacter[idx[1]]+num[2]+operatorCharacter[idx[2]]+num[3]+operatorCharacter[idx[3]]+num[4]; 16 } 17 else{ 18 f=num[0]+operatorCharacter[idx[0]]+num[1]+operatorCharacter[idx[1]]+num[2]+operatorCharacter[idx[2]]+num[3]+operatorCharacter[idx[3]]+num[4]+operatorCharacter[idx[4]]+num[5]; 19 } 20 f+="="; 21 int answer = Calculate.caculate(f); 22 if(answer>=0){ //判断题目是否符合要求 23 f+=answer; 24 } 25 else{ 26 return formula(); //生成新的符合要求的题目 27 } 28 return f; 29 }
比较当前操作符与栈顶元素操作符优先级
1 private static boolean compare(char str) { 2 if (priStack.empty()) { 3 // 当为空时,显然 当前优先级最低,返回高 4 return true; 5 } 6 char last = (char) priStack.lastElement(); 7 // 如果栈顶为'('显然,优先级最低,')'不可能为栈顶。 8 if (last == '(') { 9 return true; 10 } 11 switch (str) { 12 case '#': 13 return false;// 结束符 14 case '(': 15 // '('优先级最高,显然返回true 16 return true; 17 case ')': 18 // ')'优先级最低, 19 return false; 20 case '*': { 21 // '*/'优先级只比'+-'高 22 if (last == '+' || last == '-') 23 return true; 24 else 25 return false; 26 } 27 case '/': { 28 if (last == '+' || last == '-') 29 return true; 30 else 31 return false; 32 } 33 // '+-'为最低,一直返回false 34 case '+': 35 return false; 36 case '-': 37 return false; 38 } 39 return true; 40 }
八.总结
通过此次个人项目让我意识到大一时的java课程掌握并不牢固,对java的运用不够灵活,理解不够深入,以及数据结构和算法对编写代码的重要,就像书中说那样“程序=数据结构+算法”。关于项目对于模块化这方面,我借鉴了同学以及相关博客的思想,设计了四个类,分离出Main主类,再分别写各类,从而实现逐级调用,每个类分别实现自己的功能,在这方面还需要向其他人学习.测试的时候,在命令行出现了“找不到或无法加载主类”的情况,在网上查阅了相关内容,又看到有同学也出现了这种情况并在博客里分享了。很感谢我的同学在我困惑时对我的帮助与解答。
九.PSP展示
PSP |
任务内容 |
计划共完成需要的时间(h) |
实际完成需要的时间(h) |
Planning |
计划 |
1.5 |
1.0 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
80+ |
90+ |
Development |
开发 |
40+ |
60+ |
· Analysis |
需求分析 (包括学习新技术) |
12 |
20 |
· Design Spec |
· 生成设计文档 |
2.0 |
1.0 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
1.2 |
0.8 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
0.5 |
0.6 |
· Design |
· 具体设计 |
3 |
3.5 |
· Coding |
· 具体编码 |
20 |
25 |
· Code Review |
· 代码复审 |
2 |
3 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
2 |
4 |
Reporting |
报告 |
2 |
3 |
· Test Report |
· 测试报告 |
1.5 |
2 |
· Size Measurement |
· 计算工作量 |
0.5 |
0.5 |
· Postmortem & Process Improvement Plan |
事后总结, 并提出过程改 进计划 |
1 |
1.2 |