项目地址: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相关内容和老师推荐博客给予了很大帮助。

这次的任务,花费了不少时间,只有去实践才能进步,查缺补漏,锻炼自我。

转载于:https://www.cnblogs.com/fangnuonuo/p/8646990.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐