任务1源码可直接克隆的仓库地址:

(HTTPS)https://git.coding.net/zhaoliguaner/Calculate.git

(SSH)git@git.coding.net:zhaoliguaner/Calculate.git


需求分析

使用JAVA编程语言,独立完成一个3到5个运算符的四则运算练习的命令行软件开发。


功能分析

一、基本功能

  • 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
  • 为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。
  • 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
  • 当程序接收的参数为4时,以下为一个输出文件示例。

二、附加功能

  • 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号必须大于2个,且不得超过运算符的个数。
  • 扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。

设计实现

设计了以下函数:

1. LinkedList<String> expression()  产生运算式,在此过程中,可以产生括号

2. int[ ] operator()  产生随机操作符

3. int decide(int x,int y)  通过递归实现整除

4. int transferToPostfix(LinkedList<String> list,int n,String[] ss)  将中缀表达式转化为后缀表达式

5. int calculate(int n,String[] ss)  计算后缀表达式

6. boolean isOperator(String oper)  进行操作符的判断

7. int priority(String s)  进行操作符优先级排序

8. int cal(int num1,int num2,String operator)  进行数字间的运算

9. MakeFraction()    实现分数的出题与计算

实现了基本功能以及附加功能(产生括号和真分数计算)在括号的产生方法上,还存在一些不足之处。

显示部分代码

         /*** 产生运算符,个数及种类,并限制种类大于2。此处采用递归* @return int[] ope 返回生成的运算符*/private static int[] operator() {Random random = new Random();boolean flag = false;int n=random.nextInt(3)+3;  //3-5个运算符,运算符个数ope=new int[n];for (int j=0;j<n;j++)  ope[j]=random.nextInt(4);  //随机选择某个运算符for (int j = 1; j < n; j++) {               //控制运算符种类if(ope[0]!=ope[j]) flag = true;}if (!flag)  {operator();}return ope;}

  

   /*** 中缀表达式转化为后缀表达式* @param LinkedList<String> list* @param int n* @param String[] ss* @return int m */private static int transferToPostfix(LinkedList<String> list,int n,String[] ss){Iterator<String> it=list.iterator();while (it.hasNext()) {String s = it.next();if (isOperator(s)) {if (operators.isEmpty()) {operators.push(s);}else {//如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样,则将操作符压入栈if (priority(operators.peek())<priority(s)&&!s.equals(")")) {operators.push(s);}else if(!s.equals(")")&&priority(operators.peek())>=priority(s)){while (operators.size()!=0&&priority(operators.peek())>=priority(s)&&!operators.peek().equals("(")) {if (!operators.peek().equals("(")) {String operator=operators.pop();sb.append(operator).append(" ");                           output.push(operator);}}operators.push(s);}//如果读入的操作符是")",则弹出从栈顶开始第一个"("及其之前的所有操作符else if (s.equals(")")) {while (!operators.peek().equals("(")) {String operator=operators.pop();sb.append(operator).append(" ");output.push(operator);}//弹出"("operators.pop();}}}//读入的为非操作符else {sb.append(s).append(" ");              output.push(s);}}if (!operators.isEmpty()) {Iterator<String> iterator=operators.iterator();while (iterator.hasNext()) {String operator=iterator.next();sb.append(operator).append(" ");output.push(operator);iterator.remove();}}int m = calculate(n,ss);sb.delete(0,sb.length());return  m ;}

 

          /*** 计算后缀表达式并输出到文件* @param int n* @param String[] ss* @return int n */    private static int calculate(int n,String[] ss){LinkedList<String> mList=new LinkedList<>();String[] postStr=sb.toString().split(" ");for (String s:postStr) {if (isOperator(s)){if (!mList.isEmpty()){int num1=Integer.valueOf(mList.pop());int num2=Integer.valueOf(mList.pop());if (s.equals("/")&&(num1==0||num1>num2)){n--;return n;}if(s.equals("-")&&num2%num1!=0){n--;return n;}int newNum=cal(num2,num1,s);mList.push(String.valueOf(newNum));}}else {//数字则压入栈中mList.push(s);}}String content = "";if (!mList.isEmpty()){for (int j = 0; j < ss.length; j++) {content+=ss[j];}content+="="+mList.pop()+"\r\n";}if(!file.exists()) file = new File("result.txt");         try {FileOutputStream fos = new FileOutputStream(file,true);//建立文件流,用以输出计算式           fos.write(content.getBytes());fos.flush();fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return n;}

   产生计算式(可以加括号)

public LinkedList<String> expression(){   char[] operator=new char[]{'+','-','*','/'};Random random=new Random();LinkedList<String> expression=new LinkedList<String>();int ope[]= operator(); //产生的运算符的个数int[] number=new int[ope.length+1]; //运算数的个数,该数组存储运算数for(int j=0;j<=ope.length;j++){number[j]=random.nextInt(100)+1; //4-5个数字,产生数字//此时产生的数字是[1,10],不包括0,可以这样写,random.nextInt(20)%11//改成限制的!!!!!}int bracketnum=random.nextInt(ope.length-1); //随机产生括号的个数,题目限定括号个数小于运算符个数
//          System.out.println("括号数:"+bracketnum);if (bracketnum>0) {                   //产生括号             int [] lbracketloc=new int[bracketnum];int [] rbracketloc=new int[bracketnum];int [] leftnum=new int[ope.length+1];   //记录每个数前的左括号的数量int [] rightnum=new int[ope.length+1];  //记录每个数后的右括号的数量 for (int i = 0; i <bracketnum; i++) {lbracketloc[i]=random.nextInt(ope.length); //随机产生左括号的位置,此左括号在第几个运算数前面,运算数不包括最后一个数,rbracketloc[i]=random.nextInt(ope.length)+1;//随机产生右括号的位置,此右括号在第几个运算数后面,运算数不包括第一个数if (rbracketloc[i]<=lbracketloc[i]) {      //若右括号的位置在左括号前面或左右两个括号只括住一个数字,则去掉本次产生的括号i--;                                   //这个方法只是初次保证在一次循环下产生的左右括号不括住一个数字,但仍有可能出现这种情况  }                                           //在分次循环时,仍有可能出现括住一个数字的情况}for (int i = 0; i < bracketnum; i++) {  //利用桶函数的思想,记录每个运算数对应的括号的个数leftnum[lbracketloc[i]]++;rightnum[rbracketloc[i]]++;}for (int i = 0; i < ope.length+1; i++) { // 再次进行限制,保证左右括号不是只括住一个数字。对一个数进行检查,当其左右两边的括号数相等时,if (!(leftnum[i]==0||rightnum[i]==0)) {  // 就将它两边的括号都删掉,这样只是对单个数进行了成功的限制,但若将一个表达式作为整体看待,while (!(leftnum[i]==0||rightnum[i]==0)) {      //还是会出现这种情况         leftnum[i]--;rightnum[i]--;}}}//            if (!(leftnum[0]==0||rightnum[ope.length]==0)) {        //对式子最前面和最后面的括号进行限制,不许出现括住整体式子的情况
//                  while (!(leftnum[0]==0||rightnum[ope.length]==0)) { //这样有错误
//                      leftnum[0]--;
//                      rightnum[ope.length]--;
//                  }
//              }int right=0;  //记录加进式子的右括号的数量int left=0;  // 记录加进式子的左括号的数量for (int i = 0; i < ope.length; i++) {for (int j = 0; j < leftnum[i]; j++) {expression.add("(");left++;}expression.add(String.valueOf(number[i]));for (int j = 0; j < rightnum[i]; j++) {expression.add(")");right++;}expression.add(String.valueOf(operator[ope[i]]));if(ope[i]==3){number[i+1]=decide(number[i],number[i+1]); //此处为整除的初步控制,控制可能会无效,因为在某些情况下//加上括号后,整体的运算整个都变了,要在计算过程中去二次控制整除}                                             //在下面不加括号的处理中,也会因为运算顺序的改变而出现控制无效的情况}                                                 //所以这段代码只能初步控制整除expression.add(String.valueOf(number[ope.length]));for (int i = right; i < left; i++) {expression.add(")");}        }else {for(int i=0;i<ope.length;i++){expression.add(String.valueOf(number[i]));expression.add(String.valueOf(operator[ope[i]]));if(ope[i]==3){number[i+1]=decide(number[i],number[i+1]);}}expression.add(String.valueOf(number[ope.length]));        }
//          System.out.println(expression);    return expression;}

  混合产生真分数和整数式子

 public void Generate(int num){ //执行整数计算Random random = new Random();CalCu cu = new CalCu();int n=0;while (n<num) {int choose = random.nextInt(3);// System.out.println("suijishu:"+choose);if(choose==0||choose==1){LinkedList<String> list=new LinkedList<>();list=new CalCu().expression();Iterator<String> it=list.iterator();StringBuilder sd=new StringBuilder();while (it.hasNext()) {               sd.append(it.next()).append(" ");}String[] ss=sd.toString().split(" ");n = cu.transferToPostfix(list,n,ss);n++;}else {cu.MakeFraction();n++;}}} 

  


测试运行


项目总结

在分析了模块化的定义(模块化程序设计即模块化设计,属于计算机编程,简单地说就是程序的编写不是开始就逐条录入计算机语句和指令,而是首先用主程序、子程序、子过程等框架把软件的主要结构和流程描述出来,并定义和调试好各个框架之间的输入、输出链接关系。)之后,我在写代码的过程中,推开之前逐条去写代码的习惯,采用了一种新的方法,定义了一些子方法,并在主程序或子程序中去调用,运用这样的编程方法,觉得代码思路清晰了很多。


PSP展示

PSP

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

8

6

·        Estimate

·   估计这个任务需要多少时间,并规划大致工作步骤

8

6

Development

开发

198

481

·        Analysis

需求分析 (包括学习新技术)

30

120

·        Design Spec

·         生成设计文档

5

5

·        Design Review

·         设计复审 (和同事审核设计文档)

5

3

·        Coding Standard

·         代码规范 (为目前的开发制定合适的规范)

3

3

·        Design

·         具体设计

15

40

·        Coding

·         具体编码

80

120

·        Code Review

·         代码复审

20

40

·        Test

·         测试(自我测试,修改代码,提交修改)

40

150

Reporting

报告

9

6

·         Test Report

·         测试报告

3

2

·         Size Measurement

·         计算工作量

2

1

·         Postmortem & Process Improvement Plan

·         事后总结, 并提出过程改进计划

3

3


后记:自己之前也有敲代码,但是那些代码都比较固定,在算法上几乎没有难度,而这次的四则运算,在算法方面的要求比之前要高,所以,对我还是一个蛮大的挑战,在起初看完题目要求后,真的是觉得无从下手。在敲代码的过程中也不怎么顺,很多java的类、方法自己知道的也不多,都是在这过程当中学习的;还有相关算法(调度场算法),文件流的输出这些也是认真读了博客学习的。将代码写好测试无误后,发现还需要在命令行窗口进行编译运行,这也不同于之前的在IDE中进行编译运行,怎么办呢?再学呗。最后,又学习了git的相关知识,将项目传到encoding.net上面,并作了博客记录,整个工作才算完成。通过这次作业,我确实收获了很多,完成之后,感觉十分欣慰,因为我知道自己收获满满。而且,我发现自己现在养成了想要去记录博客的好习惯,很开心,技术和习惯上的双丰收。所以,想要感谢老师,感谢这道题,也感谢自己,谢谢。

转载于:https://www.cnblogs.com/zhaollguaner/p/8612230.html

2016012028+小学四则运算练习软件项目报告相关推荐

  1. 2016012101小学四则运算练习软件项目报告

    2016012101小学四则运算练习软件项目报告 Coding.net源码仓库地址:https://git.coding.net/naiteu/sgwq.git 一.需求分析 1,程序可以接收一个参数 ...

  2. 小学四则运算练习软件项目报告

    小学四则运算练习软件项目报告 作业源代码地址:https://git.coding.net/weijn/SiZe.git 一.需求分析 程序可接收一个输入参数n,然后随机产生n道加减乘除练习题. 每个 ...

  3. 2016012090+小学四则运算练习软件项目报告

    2016012090+小学四则运算练习软件项目报告 Coding.net原码仓库地址:https://git.coding.net/Ai_Code/Work.git 目录: 一.需求分析 二.功能设计 ...

  4. 201571030107 小学四则运算练习软件项目报告

    本文转载自:http://www.javaxxz.com/thread-359437-1-1.html 201571030107 小学四则运算练习软件项目报告 项目Github地址 Arithmeti ...

  5. 201571030334 小学四则运算练习软件项目报告

    小学四则运算练习软件项目报告 Github的仓库主页链接地址:https://github.com/huicunzhang/sizeyunsuan 一.需求分析: 1. 程序可接收一个输入参数n,然后 ...

  6. 2016012007+小学四则运算练习软件项目报告

    此次作业的源码地址:https://git.coding.net/ClausKE/Calculator1.git 写在前面:这次的作业完成得不易,在跟一些同学的交流中对这次作业有了更多的理解,在咨询了 ...

  7. 2016012033 小学四则运算练习软件项目报告

    week2的作业弄到现在week3才开始着手做,所幸截止日期还有几天. Coding.net源码仓库地址:https://git.coding.net/Agustin_Leonard_DPS/Calc ...

  8. 201571030138 小学四则运算练习软件项目报告

    项目gihub地址 fateiceb 项目过程 1.需求分析 基本功能 程序可接收一个输入参数n,然后随机产生n道加减乘除练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间. 为了让小学 ...

  9. 2016012023+小学四则运算练习软件项目报告

    零.coding链接 https://git.coding.net/hiawei/homework1.1.git 一.需求分析程序为四则运算生成器 用户为小学生 1.功能需求: 输入参数N,随机产生N ...

最新文章

  1. 注意力机制并不是关注输入的位置
  2. python树莓派串口通信实例_Python实现树莓派USB串口通讯及云端对接
  3. springboot教程-web(二)
  4. 前端学习(2656):vue2中用v-model实现
  5. linux 内核 第二周 操作系统是如何工作的
  6. Python《使用Selenium 和pyautogui 实现自动登录淘宝》
  7. unity打开一片黑_黑花儿和白花儿——记我家的两只猫星人
  8. html表格td点击事件,监听layui中的table中的td点击事件
  9. 苹果iPhone XI新爆料:用了被小米当噱头的TOF技术
  10. 什么是排他思想算法?(源码解析)
  11. 【语音去噪】基于matlab谱减法语音去噪【含Matlab源码 571期】
  12. server2012文件服务器的开始按钮,Windows Server 2012实用技巧集锦
  13. 算法:间隔重排序链表Reorder List
  14. excel如何晒出重复数据_excel怎么查找重复的内容 excel重复数据怎么筛选出来
  15. MAC QQ聊天记录迁移
  16. Foxmail登录不上163邮箱。。。
  17. IJCAI'22 | 感知图像内容的创意布局自动生成方法
  18. A simple test
  19. CAD全称AutoCAD (全系列中文版软件+注册机下载) 2004-2020 安装视频教程
  20. 计算机漫游用户的工作原理,漫游用户配置文件全攻略

热门文章

  1. 计算机考试试题库带答案
  2. 计算机的心智-操作系统之哲学原理
  3. 51单片机(动态数码管,静态数码管,led交通灯全部点亮)小白试图进阶菜鸟
  4. CGI与FASTCGI区别
  5. 笔记本换固态后开机慢(长时间卡在黑屏)
  6. 热交换器及一维平行流换热器分析(Matlab代码实现)
  7. Redis 学习笔记十 发布者订阅者模式与生产者消费者模式
  8. 自动驾驶—两轮差速机器人基于PID控制下轨迹跟踪
  9. SAP MDG —— 一些正在大规模使用MDG系统的国外公司清单(排名不分先后,持续更新中……)
  10. u盘启动 v5 华为2288h_华为2288H V5 安装Windows2012R2步骤详解