高级软件工程第二次作业

1 项目 GitHub 地址

git地址:  https://github.com/JEAN330/nangua

2 PSP

psp Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planing 计划 10 10
? Estimate ? 估计这个任务需要多少时间 10 10
Development 开发 600 900
? Analysis ? 需求分析(包括学习新技术) 60 120
? Design Spec ? 生成设计文档 20 20
? Design Review ? 设计复审 (和同事审核设计文档) 10 10
? Coding Standard ? 代码规范 (为目前的开发制定合适的规范) 10 10
? Design  ? 具体设计 30 45
? Coding ? 具体编码 350 500
? Coding Review ? 代码复审 60 100
? Test ? 测试(自我测试,修改代码,提交修改) 60 85
Reporting 报告 130 190
? Test Report ? 测试报告 100 150
? Size Measurement ? 计算工作量 10 10
? Postmortem & Process Improvement Plan ? 事后总结, 并提出过程改进计划 20 30
合计   740 1100

3 项目要求

  •  参与运算的操作数(operands)除了100以内的整数以外,还要支持真分数的四则运算。操作数必须随机生成。
  •  运算符(operators)为 +, ?, ×, ÷ 运算符的种类和顺序必须随机生成。
  •  要求能处理用户的输入,并判断对错,打分统计正确率。
  •  使用 -n 参数控制生成题目的个数。
附加要求
  • × 支持带括号的多元复合运算
  •  运算符个数随机生成(考虑小学生运算复杂度,范围在2~10)

4 解题思路

  在第一次看到这道题时,我就觉得这道题挺复杂的,果然,有一个附加功能我还没有实现。先不考虑括号的功能,这道题对于我来说的难点有以下几点:

  1、如何实现真分数与整数或真分数与真分数的计算

  2、如何随机生成一个合理的表达式

  3、如何将表达式计算出来

  4、如何将用户输入的结果与正确答案进行比较

  这些问题的解决方法如下:

  1、分数以分子、分母的形式保存在二维数组中,整数以分子、1的形式保存在二维数组中,即将所有的数都以分数的形式保存,并用分数的计算方法计算。

  2、随机生成m个分数与n个整数,随机生成m+n-1个运算符,数的排列顺序随机排序,并将数和符号依次排列

  3、将表达式转换为逆波兰表达式再计算,虽然之前学过,但是已经忘得差不多了,所以还是需要重新学习

  4、将用户输入的结果和正确答案以字符串的形式进行比较

5 代码说明

1、真分数生成

public static int[] fraction() {    //定义一个真分数
         int x=(int)(Math.random()*10)+1;  //随机生成10以内的不为0的分子分母
         int y=(int)(Math.random()*10)+1;
         if(x<=y){
             return gcd(x,y);
         }
         else{
             return gcd(y,x);
         }
     }

2、分数化简

 public static int[] gcd(int x,int y){   //辗转相除得到最简分数
         int temp,x1=x,y1=y;
         if(x>=y)         //假分数化简
         {
             while(x!=y){
                 temp=y;
                 if((x-y)<=temp){    //比较减数与被减数的大小,将大的值赋予x,小的值赋予y
                     y=x-y;
                     x=temp;
                 }
                 else{
                     x=x-y;
                     y=temp;
                 }
             }
         }
         else             //真分数化简
         {
             while(x!=y){
                 temp=x;
                 if((y-x)<=temp){
                     x=y-x;
                     y=temp;
                 }
                 else{
                     y=y-x;
                     x=temp;
                 }
             }
         }
        int[] array={x1/x,y1/y};
        return array;
     }

3、随机生成表达式

 public static int[] display(int n,int m,int[] a,int[][] b,int[] op){
         int i,j,k,l;
         int[] order=new int[20];  //为整数和真分数排序
         for(i=0,j=0,k=0,l=0;k<m+n;)  //随机排列整数和真分数
         {
             int x=(int)(Math.random()*2);
             if(x==0&&i<n)
             {
                 order[k]=0;
                 System.out.print(a[i]);
                 if(k<m+n-1)
                 {
                     switch(op[l])
                     {
                         case 0:System.out.print("+");break;
                         case 1:System.out.print("-");break;
                         case 2:System.out.print("*");break;
                         case 3:System.out.print("÷");break;
                     }
                     l++;
                 }
                 k++;
                 i++;
             }
             if(x==1&&j<m){
                 order[k]=1;
                 System.out.print(b[j][0]+"/"+b[j][1]);
                  if(k!=m+n-1)
                 {
                     switch(op[l])
                     {
                         case 0:System.out.print("+");break;
                         case 1:System.out.print("-");break;
                         case 2:System.out.print("*");break;
                         case 3:System.out.print("÷");break;
                     }
                     l++;
                 }
                  j++;
                  k++;
             }
         }
                System.out.print("=");
                return order;
     }

4、转换为逆波兰表达式

 public static int[] res(int[] a,int b[][],int[] op,int[] order,int n,int m){ //将中缀表达式转换为后缀表达式
        stack<Integer> stack = new arraystack<Integer>();
        int i=0,j=0,o,k,l;
        int[] arr=new int[2];
        int[][] c=new int[30][2];
        stack.push(op[0]);
        if(order[0]==0)  //将整数以整数/1的形式存入数组,便于之后的计算
        {
            c[0][0]=a[i];
            c[0][1]=1;
            i++;
        }
        else{
            c[0][0]=b[0][0];
            c[0][1]=b[0][1];
            j++;
        }
        for(k=1,l=1,o=1;k<n+m;k++){  //将中缀表达式按照逆波兰表达的顺序存入二维数组
            if(order[k]==0){
                c[o][0]=a[i++];
                c[o][1]=1;
                o++;
            }
            else{
                c[o][0]=b[j][0];
                c[o++][1]=b[j++][1];
            }
            if(l<(m+n-1)){
                while(!stack.isEmpty()&&precedence(stack.peek(),op[l])>=0){
                    switch(stack.pop()){
                        case 0:c[o][0]=0;c[o++][1]=0;break;
                        case 1:c[o][0]=0;c[o++][1]=1;break;
                        case 2:c[o][0]=0;c[o++][1]=2;break;
                        case 3:c[o][0]=0;c[o++][1]=3;break;
                    }
                }
                stack.push(op[l++]);
            }    

        }
        if(!stack.isEmpty()){
            int length=stack.length();
            for(i=0;i<length;i++){
                switch(stack.pop()){
                case 0:c[o][0]=0;c[o++][1]=0;break;
                case 1:c[o][0]=0;c[o++][1]=1;break;
                case 2:c[o][0]=0;c[o++][1]=2;break;
                case 3:c[o][0]=0;c[o++][1]=3;break;
                }
            }
        }
        arr=calculate(c,n,m);
        return arr;
     }

5、计算

public static int[] calculate(int[][] c,int n,int m){
         int i,w,x,y,z;
         int[] arr=new int[2];
         stack<Integer> stack = new arraystack<Integer>();
         for(i=0;i<2*m+2*n-1;i++){
             if(c[i][0]==0){
                z=stack.pop();y=stack.pop();x=stack.pop();w=stack.pop();
                switch(c[i][1]){
                case 0:arr=cal(w,x,y,z,0);stack.push(arr[0]);stack.push(arr[1]);break;
                case 1:arr=cal(w,x,y,z,1);stack.push(arr[0]);stack.push(arr[1]);break;
                case 2:arr=cal(w,x,y,z,2);stack.push(arr[0]);stack.push(arr[1]);break;
                case 3:arr=cal(w,x,y,z,3);stack.push(arr[0]);stack.push(arr[1]);break;
                }
             }
             else{
                 stack.push(c[i][0]);
                 stack.push(c[i][1]);
             }
         }
         arr[1]=stack.pop();
         arr[0]=stack.pop();
         return arr;

     }

6 测试运行

通过输入参数3,可以自动生成3个算式

测试不同的方法,所得结果如下:

其中main()的测试中,默认用户输入值为0,且随机生成的算式个数为1000。

7 个人小结

  本次实验对我来说算是一个小小的考验,所完成的项目还有很多瑕疵,比如括号的功能没有实现,随机生成的数总是设置为正数,避免除数和分母为0的情况。并且只有在输入最简分数时才能判定为正确,未化简的情况以及带分数的情况都判定为错。而且从测试结果来看,当需要生成足够多的算式时,运行速度过慢,所以这次实验还有很多需要优化的地方,由于时间原因,只能仓促完成,但是之后的时间里我还是会继续完善这个项目,包括实现括号,提高项目性能等。这次实验我看到了我很多的缺点,基础知识薄弱,动手能力差,希望能在接下来的学习中继续提升自己。

时间: 2024-08-04 15:16:00

高级软件工程第二次作业的相关文章

软件工程 第二周作业

##软件工程第二周作业 提出问题 1. 一般来说,想要自己的程序跑得又快又好,就要减少函数的反复调用,但有所得则必有所失,效能提高就有可能伴随着程序的稳定性的降低,这两者应该如何权衡呢? 2. 关于5.3.5 老板驱动的流程,这种开发流程模式存在着一些问题,那要如何解决这些问题呢? 这种模式当然也有它的问题. 领导对许多技术细节是外行. 领导未必懂得软件项目的管理,领导的权威影响了自由的交流和创造. 领导最擅长的管理方式是行政命令,这未必能管好软件团队或任何需要创造力的团队. 领导的精力有限,领

2017秋-软件工程第二次作业

本周因为个人缘故,参加社团活动作业没能及时完成.对此我表示,做过就不后悔,至少我觉得生活是丰富多彩的,错过的时间就应该努力赶上!夜深人静的时候总是可以让人反省自己.本次作业我只实现了第一个功能和第二个功能的部分.对此我表示很不满,但是时间紧迫.个人能力有限,以至于自己没能让自己的软件看起来完美. 第二次作业的内容非常有趣,这也是我一直想做的一件事情,统计一篇文章里的字词.我知道自己的编程能力较差.距离完成提交时间很近,自己手写全部是不能及时按照约定提交的,于是就尝试借鉴前人的代码.第一晚的努力各

软件工程第二次作业--师兄采访

我采访的是李权师兄,虽然之前也有人采访过他,问题都是同样的问题,不过我挖掘出了和其他同学不一样的信息. 问题:    师兄,当时你们做的项目是什么,有多少用户, 现在还有人用吗? 李权师兄: 当时我们的项目名是约跑APP,当时用户有8人.在用户的手机上测试通过,能让用户找到一起跑步的小伙伴.现在已经没有人用了. 追问:该app给用户提供了什么样的服务? 李权师兄:app能提供给用户认识新朋友的平台.通过app,用户可以约人一起跑步. 第二个问题:师兄这个项目能否给我们团队继续开发,源代码还有么?

软件工程第二次作业(王伟东)

一周的时光转瞬即逝,第二周的作业也悄悄地开始了.杨老师的一言一行都深深地刻在我的心里,"不迟到"是做人做事的根本,努力则是成就人生的基石.正如<道德经>中所言"天地不仁,视万物为刍狗",上天对待世间万物是公平的,从来都是不偏不倚,只有勤奋好学的人才会得到垂青和奖赏. ㈠词频统计的四个功能 ①首先控制台输入内容到文件中,再对文件进行词频统计: ②命令行输入英文作品名,然后统计作品词频: ③命令行输入英文作品文件的目录名,再批量统计: ④从控制台读入英文单篇

软件工程第二次作业——git的使用

1. 参照 http://www.cnblogs.com/xinz/p/3803109.html 的第一题,每人建立一个GitHub账号,组长建立一个Project,将本组成员纳入此Porject中的Collaborators,并添加[email protected] 为Collaborator.   邓杰: 陈宗雷: (1)在之前已经建立了自己的github账号,账号名称为zongleichen. (2)以合作者身份加入到组长建立的项目: 2.   每人自己建立一个HelloWorld项目,练

软件工程——第二次作业(2)

施工中-- 作业要求:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/922 项目要求是编写出一个拥有"词频统计"功能的小程序,作为一个小程序,若只是实现基本的词频统计功能,其实并不是很难.但是,如果再附加一些需求和功能的话就会让我感到有点难度了,更何况为了以后课程的要求,我选择使用Visual Studio 2015编译器和C#语言这两种从未学过的工具,在4-5天之内共10个小时左右(预计,但是实际上确实是花了更多时间

软件工程 — 第二次作业

一 :对软件工程的疑惑 1. 学习软件工程需要哪些基础? 2.程序设计语言没学好有关系吗? 3. 软件工程的发展前景? 4. 软件工程具体做什么? 5. 软件工程可作为物联网的应用层需要哪些协议来处理 二:选取三种软件并说明特点 1.支付宝 (1)优点:支付方便快捷,使用时效率高        缺点:有时会出现不安全现象,相比银行而言会存在财产丢失的问题        通过余额宝的高额利息,和即时存取的便利吸引客户,以盈利为目的 (2)经人介绍使用,自己下载 (3)定期维护更新版本 (4)开创时

软件工程第二周作业:代码规范和代码复审

0x01 :代码规划的要求 Q:这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西.(反驳) 首先,我们需要明确编码规范的定义,编码规范同时包括了编码风格和其它规范(代码设计上的规范,如设计模式.程序设计.模块之间的逻辑关联等). 编码风格,牵扯到“缩进.空格使用.注释.命名习惯”等多方面的因素,是依致特定编程语言制定的软件工程开发的“约定”,而相同的编码风格,可以使得软件开发过程中轻松浏览任意一段代码,充分保证不同的开发人员能够依据统一的编码格式轻松理解代码的逻

软件工程第二次作业 词频统计

1.项目名称:词频统计 2.代码地址:https://coding.net/u/songyuu/p/python_wf/git 3.代码如下: 1 import os 2 import re 3 import collections 4 #print(os.getcwd()) #显示wf.py路径 5 #print(os.listdir())#显示目录下的文件 6 file_name=input("wf ") 7 if not os.path.isfile(file_name+'.tx