Coding.net地址:https://git.coding.net/sixtyseven/operation.git
因本人之前学习偏重问题,java基础过差,以及时间等缘故,未能完成全部任务要求,运算结果出现负数,此次作业后,我会进一步学习请教,争取完成所有任务要求。
- 需求分析
- 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题
- 每个数字在 0 和 100 之间,运算符在3个到5个之间
- 每个练习题至少要包含2种运算符
- 练习题在运算过程中不得出现负数与非整数
- 功能设计
- 基本功能:根据用户输入的题目数量,生成符合要求的四则运算式并得出答案
- 扩展功能:无
- 设计实现
共四个类
-
GetExpresshion:此类用于生成输出表达式
-
GetResult:用于计算生成表达式的结果
Main:主方法类ToolClassDemo:用于放置方法,属于工具类
-
- 算法详解
-
public static void GetResult() { //运算混合四则运算方法,利用栈实现 Stack<String> number = new Stack<String>();//创建一个存储数字或符号的栈 Stack<Character> operate = new Stack<Character>();//创建一个存储操作符的栈 int p = (int) (Math.random() * 2) + 2;// p则是产生简单等式的次数,这里取2或3,以保证运算符为3个或5个 String str1 = GetExpresshion.getStack3().toString();//把stack3转化为字符串;产生一个四则运算题目 str1 = str1.replace("[", ""); str1 = str1.replace("]", ""); str1 = str1.replace(",", ""); str1 = str1.replace(" ", ""); String question = str1; int len = question.length(); int k = 0;//k是遍历字符串的一个参数 int same=0; for (int j = -1; j < len - 1; j++) {//把题目字符串进行拆分,拆分出数字和运算符,分别进行存储 if (question.charAt(j + 1) == '+' || question.charAt(j + 1) == '-' || question.charAt(j + 1) == '*' || question.charAt(j + 1) == '÷' || question.charAt(j + 1) == '(' || question.charAt(j + 1) == ')' || j == len - 2) { if (j == -1) {//如果第一个就是运算符,即左括号,存储在操作符栈中 operate.push(question.charAt(0)); } else if (j == len - 2) {//如果到字符串的最后了,直接存储到数字栈 number.push(question.substring(k)); break; } else { if (k <= j) { number.push(question.substring(k, j + 1));//是数字的话存储到数字这个栈中 } if (operate.empty() || question.charAt(j + 1) == '(') {//操作符栈为空或者接下来的符号是左括号的话都直接存储到操作符栈中 operate.push(question.charAt(j + 1)); } else if ((operate.peek() == '+' || operate.peek() == '-') && (question.charAt(j + 1) == '*' || question.charAt(j + 1) == '÷')) { operate.push(question.charAt(j + 1));//如果将要放入栈中的运算符优先级比栈顶元素高,直接入栈 } else if (operate.peek() == '(') {//栈顶是左括号的话,下一个操作符也直接入栈 operate.push(question.charAt(j + 1)); } else if (question.charAt(j + 1) == ')') {//下一个操作符是右括号的话,弹出操作符栈顶元素并压入数字栈中 number.push(String.valueOf(operate.pop())); if (!operate.empty()) { operate.pop(); } } else {//操作符是同等优先级的时候,把栈顶元素弹出压入数字栈中,并把下一个操作符压入操作符栈中 if(operate.peek()==question.charAt(j + 1)){ same++; } number.push(String.valueOf(operate.pop())); operate.push(question.charAt(j + 1)); } } k = j + 2; } } if(same==p+2){//判断题目的符号是否都相同 same=1; } while (!operate.empty()) {//最后把操作符栈中剩余的元素都压入数字栈中 number.push(String.valueOf(operate.pop())); } String[] result = new String[20]; int k1 = 0; while (!number.empty()) {//把数字栈中的元素也就是形成的后缀表达式存储在数组中 result[k1] = number.pop(); k1++; } for (k1 = k1 - 1; k1 >= 0; k1--) {//逆序遍历数组,运算得到的后缀表达式 if (!result[k1].equals("+") && !result[k1].equals("-") && !result[k1].equals("*") && !result[k1].equals("÷")) {//是数字的话,先压入栈中 number.push(result[k1]); } else { int a1 = 0; int b1 = 0; if (!number.empty()) {//弹出两个数进行相应运算 b1 = Integer.parseInt(number.pop()); } if (!number.empty()) { a1 = Integer.parseInt(number.pop()); } if (result[k1].equals("+")) {//如果是加号的话,弹出两个数相加 int c1 = a1 + b1; number.push(String.valueOf(c1)); } else if (result[k1].equals("-")) { int c1 = a1 - b1; number.push(String.valueOf(c1)); } else if (result[k1].equals("*")) { int c1 = a1 * b1; number.push(String.valueOf(c1)); } else { int c1 = a1 / b1; number.push(String.valueOf(c1)); } } }
利用栈,运算四则运算,实现计算生成表达式的结果
-
- 测试运行
- 总结
刚开始写作业时,未能考虑太多,直接敲代码进行书写,但因基础薄弱考虑不周,结果到最后第一版的代码完全没有办法使用,最后只能废弃,也因此耽误了非常多的时间,第二版时,学习了同学的分类方法,建立了工具类,才完成了部分作业,但因时间有限,很多功能未能完善,还有很多问题等待处理,所以会继续学习,争取之后按照所有要求彻底完善项目。
- 展示PSP
PSP |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
30 |
30 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
10 |
12 |
Development |
开发 |
960 |
2200 |
Analysis |
需求分析 (包括学习新技术) |
60 |
60 |
Design Spec |
生成设计文档 |
0 |
0 |
Design Review |
设计复审 (和同事审核设计文档) |
0 |
0 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
7 |
10 |
Design |
具体设计 |
80 |
170 |
Coding |
具体编码 |
600 |
1200 |
Code Review |
代码复审 |
40 |
240 |
Test |
测试(自我测试,修改代码,提交修改) |
10 |
40 |
Reporting |
报告 |
90 |
240 |
Test Report |
测试报告 |
25 |
190 |
Size Measurement |
计算工作量 |
6 |
10 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
40 |
40 |