结对对象:许峰铭

一.Github项目地址:https://github.com/Leungdc/Leungdc/tree/master/%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97/ASMDframe

二.PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

560

1440

· Estimate

· 估计这个任务需要多少时间

120

180

Development

开发

2000

2160

· Analysis

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

360

360

· Design Spec

· 生成设计文档

120

180

· Design Review

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

60

120

· Coding Standard

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

60

90

· Design

· 具体设计

150

300

· Coding

· 具体编码

2000

2160

· Code Review

· 代码复审

60

60

· Test

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

300

540

Reporting

报告

120

180

· Test Report

· 测试报告

30

30

· Size Measurement

· 计算工作量

20

20

· Postmortem & Process Improvement Plan

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

20

20

合计

5980

7840

三. 效能分析

对于改进程序效能都是在刚开始构思该功能如何实现的时候想好的,通过实现改功能想法的相互对比,然后留下最好的方法,功能实现后就没有对方法进行很大的变动。在实现运算逻辑这一功能的时候是花费时间最多的,总共花费了两天的时间去实现这一功能,这一功能要考虑符号的优先级,包括括号和操作符等,由于使用的是栈存取数,要考虑存入的数据,和取出的方式。但栈只能先进后出,不能先取出头部数据,后改为用链栈进行数据的存储,从而使功能得以实现。

为了提速而改变数据结构的耗时:≈总耗时*0.2

    1.该课设中大量使用StringBuilder类型数据而不是String是因为有对字符串频繁的增删查操作,节省了许多耗时

    2.查重算法中本是用出栈的方式一个一个出栈然后对比查重,但是考虑到时间较慢,就用了String类型数组来存放整个中间结果数据来对比查重

最耗时函数:calculate()函数

    calculate函数是对两个数字的解析函数,因为操作符两边的数字使用String来存放的,首先calculate函数需要解析该数据的数据类型(是整数还是分数)

    然后化为假分数,再根据不同的操作符做不同的运算,其中该函数执行一次要调用至少六次其他方法。

四.设计实现过程

 1.生成随机数算法

  生成随机数看似简单,但是涉及到的方法却不少,主要包括三种数 整数 带分数 真分数

  整数:直接用random方法生成

  带分数和分数:首先要将分子n和分母m分开生成,在这生成之间

    第一个要注意的点是:n%m!=0;1.屏蔽了分子和分母相等的情况  2.屏蔽了分子除与分母为整数的情况

    第二个要注意的点是:要对分子分母进行通分,我们的代码就使用了欧几里得方法求最大公约数,然后约分

    第三个要注意的点是:若n>m,则是带分数,先要用一个carrier来表示带分数的“带”,然后n=n%m;

    第四个要注意的点是:对于特别情况的屏蔽,例如m=1或m=0或n=0或carrier=0;都是不可取的

2.两个数的运算

  只研究两个数的运算而不是三个数的运算,是因为在确定好运算逻辑的前提下,我们可以多次地调用运算两个数的方法,来得到我们最后的答案,下面介绍两个数运算的主要思路:

    1.采用假分数的计算方法;首先将所有的数转换成假分数如5=5/1,  6'7/8=55/8,  然后分别取这两个数的分子分母,根据不同的运算符,做不同的运算

    如:5÷6'7/8    第一步:5=5/1,n1=5,m1=1  6'7/8=55/8,n2=55 m2=8    第二步:N=n1*m2=5*8  M=m1*n2  最后再把n和m之间通分,若是带分数就转为带分数。

    由于这个运算方法要求可以服务于输出最终结果,所以运算的中间结果我们都用了题目要求的最终结果的格式(1或5'3/5或7/8)

3.随机运算式的生成

    1.先生成随机个运算符n

    2.再生成随机个运算数字m

    3.在1和2的基础上插空生成括号

        经研究,包括无括号的情况,共有对于3个运算符一共有13种括号的生成可能,分别为:    

          一、1运算符2数字 不能生成括号

          二、2运算符3数字 只能是单括号,包含以下情况
            1. (1+2)+3
            2. 1+(2+3)

          三、3运算符4数字 单括号或双括号,包含以下情况

          单括号:
            3. (1+2)+3+4
            4. (1+2+3)+4
            5. 1+(2+3)+4
            6. 1+(2+3+4)
            7. 1+2+(3+4)

          双括号:
            8. (1+2)+(3+4)
            9. ((1+2)+3)+4
            10. (1+(2+3))+4
            11. 1+((2+3)+4)
            12. 1+(2+(3+4))

            13.1+2+3+4(无括号情况)

    我们采用枚举方式列出所有括号情况然后生成

 5.查重算法

   经过对四则运算的运算顺序的反复推敲后,我们得出了以下的运算优先级。

   靠左边的括号内运算>靠右边的括号内运算>最靠左的乘法运算=最靠左的除法运算>靠右的乘法运算=靠右的除法运算>从左至右运算>最靠左加法运算=最靠左减法运算>靠右的

加法运算=靠右的减法运算;

   查重算法思路:

    ①从左至右扫描式子的第一个左括号,并记录位置,若无,则直接跳到③

    ②从左至右扫描式子的第一个右括号,截取①中左括号位置到②中第一个右括号位置之间的式子,并递归返回①,直到跳到③为止

    ③判断括号内(或无括号内)操作符的优先级高低,对最高优先级操作符的左右两边的数字进行运算,得到中间值,第一操作符a,将操作符和操作的两个数字压进过程栈,再判断

    括号内(或无括号内)次优先级的操作符是什么,再算出中间结果,再将操作符合操作的两个数字押进过程栈,最后对比所有式子的过程栈是否存在相同的,若有,则重新生成式子

    例如1+2+3的过程栈为+21+33;而3+2+1的过程栈为+32+51;又如3+(2+1)的过程栈为+21+33;与第一个式子的过程栈相同,则删掉重新生成式子。

五.代码说明

1.输入题目的数量num,和数字的范围range,调用GenerateEquation()生成式子,然后定义一个Calculator类对象并调用algorithm方法得到式子答案和式子的运算顺序,再用if语句判断返回答案是否为空,或式子的运算顺序已经存在,则重新生成式子。

 private  void CreatProblems(int num,int range) {
        
        Random rand=new Random();
        
    while(Count<num) {
            
    int[] operator=GenerateOpertor(operatorNum,rand); //随机生成operatorNum个字符        
        String equation=GenerateEquation(operator,operdataNum,range);       
        Calculator answer=new Calculator();
        list=answer.algorithm(equation);        
         if(!list.isEmpty()) {
             String STR=Sb.toString();
             if(STR.indexOf(list.get(1).toString())==-1) {
                 Sb.append(list.get(1)).append(" "); 
                
                 problemTemp.append("第").append(Integer.toString(Count+1)).append("题:").append(equation).append("\n");
                 
                 answerTemp[Count]=list.get(0).toString();                     
                  System.out.println(answerTemp[Count]); 
                 Count++;
             }
         }else{
             CreatProblems(num-Count,range);    
         }                 
       }
    }

2.

/*
     * 随机生成operatorNum个字符,并生成一个数组储存(下标数组)
     */    
    private  int[] GenerateOpertor(int operatorNum, Random rand) {    
        int[] operator=new int[operatorNum];
        for(int i=0;i<operatorNum;i++) {
            operator[i]=rand.nextInt(4);
        }
        return operator;    
    }

3.

/**
     * 生成随机数算法
     */
    
    private String getRandomNum(int limit){
        Random all = new Random();
        StringBuilder temp = new StringBuilder();
        int numtype = all.nextInt(2);
        int num = 0, carrier=0, numerator = 0, denominator = 0;
        int j = 0;
        if(numtype==0){
            num=1+all.nextInt(limit);
            return Integer.toString(num);
        }
        else{
            //此行生成分数
            numerator = 1+all.nextInt(limit);
            denominator = 2+all.nextInt(limit-1);        
            int n = numerator, m = denominator;
            if(n%m==0) {            //如果生成的分子分母不规范
            for(int i= 0 ; i<=100; i++){
                n = 1+all.nextInt(limit);
                m = 2+all.nextInt(limit-1);
                if(n%m!=0) break;
            }
        }
            if(m>n)   j = Euclid(m, n);
            else{
                 carrier = n/m;
                 j = Euclid(n,m);        
            }
            if(j==1){                          //判断最大公约数是否等于1;
                if(carrier!=0){                //判断该分数是不是假分数,是就转成带分数形式      
                    n=(n%m);
                    temp.append(carrier);
                    temp.append("'");
                    }
                temp.append(n);
                temp.append("/");
                temp.append(m);
                return temp.toString();
            }
            else{                    //判断该分数是不是假分数,是就转成带分数形式
                n/=j;
                m/=j;
                if(carrier!=0){  
                    n=(n%m);
                    temp.append(carrier);
                    temp.append("'");
                }
                temp.append(n);
                temp.append("/");
                temp.append(m);
                return temp.toString();            
            }
 
        }
}
    
    /**
     * 欧几里得判断是否有公约数
     */
    private  int Euclid(int m,int n){
        while(n!=0){
            int r;
            r=m%n;
            m=n;
            n=r;
            Euclid(m,n);
            }
        return m;
        }

4.用于计算式子的结果,计算逻辑在第四部分有逻辑图

public class Calculator {
       public ArrayList algorithm(String str) { 
          LinkedList<String> numList=new LinkedList<>();//存放数字
          Stack<String> operatorStack=new Stack<>();//放操作符
          HashMap<String,Integer> hashMap=new HashMap<>();//存放字符优先级
          hashMap.put("(", 0);
          hashMap.put("+", 1);
          hashMap.put("-", 1);
          hashMap.put("*", 2);
          hashMap.put("÷", 2); 
          ArrayList list=new ArrayList();
          
          CheckOut check=new CheckOut();//生成运算顺序,用于查重 
          StringBuilder ba = new StringBuilder();
          
          String str1[]=str.split("\\ ");//            for(String string:str1)//                    System.out.println(string);
            
            
              int leftBrankets = 0;//用于检测‘(’的个数
              int operatorCount=0;
              
          for(int i=0;i<str1.length;i++) {
             
             
              StringBuilder digit=new StringBuilder();
              if(!"".equals(str1[i])) {
                 
                  //判断是否是数字
                  char num[]=str1[i].toCharArray();
                  if(Character.isDigit(num[0])) {
                      //                     System.out.println(str1[i]);                     
                     numList.addLast(String.valueOf(str1[i]));//压进数字栈
                     continue;//结束本次循环,回到for语句                         }
                  
                  //不是数字,是符号
                  else {
                     
                      char operatorOfChar=str1[i].charAt(0);
                      //                      System.out.println(operatorOfChar+"符号");
                      
                      switch(operatorOfChar) {
                      case '(':{
                          leftBrankets++;
                          break;
                      }
                      
                      case ')':{
                          String stmp;//取符号栈元素,考虑到(1+2*3)+4这种情况,要比较操作符的优先级                          String stmd;
                          if(!operatorStack.isEmpty()) {
                              
                              if(operatorCount==2&&leftBrankets==1) {
                                //取出符号栈里的操作符(两个)
                                  stmp=operatorStack.pop();
                                  stmd=operatorStack.pop();
                                  if(hashMap.get(stmp)>hashMap.get(stmd)) {
                                      String a=numList.removeLast();
                                      String b=numList.removeLast();
                                      String result=calculate(b,a,stmp);
                                     
                                      if(result.contentEquals("出现了负值"))
                                          return list ;
                                      ba.append(check.checkOut(b, a, stmp));
                                    
                                      
                                      numList.push(result);//将结果压入栈
                                      operatorStack.push(stmd);//将未进行计算的操作符压回符号栈
                                      stmp = operatorStack.pop(); //符号指向下一个计算符号,再进行一次运算
                                      String c=numList.removeLast();
                                      String d=numList.removeLast();
                                      String result02=calculate(d,c,stmp);
                                      if(result02.contentEquals("出现了负值"))
                                          return list ;
                                      ba.append(check.checkOut(d, c, stmp));
            
                                      
                                      numList.push(result02);//将结果压入栈                                      
                                  }else {
                                      String a=numList.removeFirst();
                                      String b=numList.removeFirst();
                                      String result=calculate(a,b,stmd);
                                      if(result.contentEquals("出现了负值"))
                                          return list ;
                                      ba.append(check.checkOut(a, b, stmd));
                                    
                                      
                                      numList.addLast(result);
                                      operatorStack.push(stmp);
                                      stmp = operatorStack.pop(); //符号指向下一个计算符号
                                      String c=numList.removeLast();
                                      String d=numList.removeLast();
                                      String result02=calculate(d,c,stmp);
                                      if(result02.contentEquals("出现了负值"))
                                          return list ;
                                      ba.append(check.checkOut(d, c, stmp));
                                    
                                      
                                      numList.push(result02);//将结果压入栈                                  }
                              }else if(leftBrankets==2||(operatorCount==1&&leftBrankets==1)){
                                  stmp=operatorStack.pop();
                                  String a=numList.removeLast();
                                  String b=numList.removeLast();
                                  String result=calculate(b,a,stmp);
                                  if(result.contentEquals("出现了负值"))
                                      return list ;
                                  ba.append(check.checkOut(b, a, stmp));
                                
                                  numList.addLast(result);
                                  /*判定下一个str[i]是什么*/
                                  
                              }
                              break;  
                          }
                      }
                      
                      
                      case '=':{
                          String stmp;
                          while (!operatorStack.isEmpty()) { //当前符号栈里面还有+ - * /,即还没有算完
                              stmp = operatorStack.pop();
                              String a = numList.removeLast();
                              String b = numList.removeLast();
                              String result = calculate(b, a, stmp);
                              if(result.contentEquals("出现了负值"))
                                  return list ;
                              ba.append(check.checkOut(b, a, stmp));//                                  System.out.println(ba.toString());                                  
                              numList.addLast(result);
                          }
                          break;
                      }
                      
                      default:{
                          operatorCount++;
                        String stmp;
                         while (!operatorStack.isEmpty()&&leftBrankets==0) { //如果符号栈有符号
                             stmp = operatorStack.pop(); //当前符号栈,栈顶元素
                             if (hashMap.get(stmp) >= hashMap.get(String.valueOf(operatorOfChar))) { //比较优先级
                                 String a = numList.removeLast();
                                 String b = numList.removeLast();
                                 String result =calculate (b, a, stmp);
                                 if(result.contentEquals("出现了负值"))
                                     return list ;
                                 ba.append(check.checkOut(b, a, stmp));
                                 numList.addLast(result);
                             }else {
                                 operatorStack.push(stmp);
                                 break;
                                }
                             }
                         operatorStack.push(String.valueOf(operatorOfChar));
                         break;
                         }
                      
                      }
                      
                  }
                     
              }
                    
          }
          list.add(numList.getLast());
          list.add(ba);
          
           return list; 
       }
       
//       }
       /**
        * 计算结果
        */    
   private String calculate(String s1, String s2, String processor){
           int theinteger=0, theN=0, theM = 0;
           int position1 = -1,  position2 = -1;
           int  j = 1;   //放最大公约数
           String num1 = null, num2 =null;
           StringBuilder temp = new StringBuilder();
           int Nfornum1 = 0, Mfornum1 = 0, Nfornum2 = 0, Mfornum2 = 0;  
           int carrier1 = 0, carrier2 = 0;
           num1 = s1.substring(0);
           num2 = s2.substring(0);
           position1 = num1.indexOf("'");
           position2 = num1.indexOf("/");
           if(processor.equals("+")){
               Mfornum1 = gettheM(num1);        //确定加号前面的数字的分母值(此处要保证该数字的最后一位元素是空格)
               Nfornum1 = gettheN(num1, Mfornum1);    //确定加号后面的数字的分子值(此处要保证该数字的0号元素为数字,最后一位是空格(整数情况))
               Mfornum2 = gettheM(num2);        //"2'4/21 "
               Nfornum2 = gettheN(num2, Mfornum2);    //" 89"
               theN = Nfornum1*Mfornum2+Nfornum2*Mfornum1;
               theM = Mfornum1*Mfornum2;
               if(theN>theM){
                   j=Euclid(theN,theM);
                   carrier1 = theN/theM;
                   }
               else
                   j=Euclid(theM,theN);
               theN/=j;
               theM/=j;
               if(theN%theM==0){
                   theN = theN/theM;
                   temp.append(Integer.toString(theN));
               }
               else{
                   if(carrier1!=0){                //判断该分数是不是假分数,是就转成带分数形式      
                       theN=(theN%theM);
                       temp.append(carrier1);
                       temp.append("'");
                       }
                   temp.append(Integer.toString(theN));
                   temp.append("/");
                   temp.append(Integer.toString(theM));
               }
               return temp.toString();
           }
           else if (processor.equals("-")){
                   Mfornum1 = gettheM(num1);        //确定加号前面的数字的分母值(此处要保证该数字的最后一位元素是空格)
                   Nfornum1 = gettheN(num1, Mfornum1);    //确定加号后面的数字的分子值(此处要保证该数字的0号元素为数字,最后一位是空格(整数情况))
                   Mfornum2 = gettheM(num2);        //"2'4/21 "
                   Nfornum2 = gettheN(num2, Mfornum2);    //" 89"
                   theN = Nfornum1*Mfornum2-Nfornum2*Mfornum1;
                   theM = Mfornum1*Mfornum2;
                   if(theN==0){
                       temp.append("0");
                       }
                   else if(theN>0){
                       if(theN>theM){
                           j=Euclid(theN,theM);
                           carrier1 = theN/theM;
                           }
                       else
                           j=Euclid(theM,theN);
                       theN/=j;
                       theM/=j;
                       if(theN%theM==0){
                           theN = theN/theM;
                           temp.append(Integer.toString(theN));                    }
                       else{
                           if(carrier1!=0){                //判断该分数是不是假分数,是就转成带分数形式      
                               theN=(theN%theM);
                               temp.append(carrier1);
                               temp.append("'");
                               }
                           temp.append(Integer.toString(theN));
                           temp.append("/");
                           temp.append(Integer.toString(theM));
                       }
                   }
                   else{
                       temp.append("出现了负值");
                       
                       }
           return temp.toString();
       }
           
           else if (processor.equals("*")){
               Mfornum1 = gettheM(num1);        //确定加号前面的数字的分母值(此处要保证该数字的最后一位元素是空格)
               Nfornum1 = gettheN(num1, Mfornum1);    //确定加号后面的数字的分子值(此处要保证该数字的0号元素为数字,最后一位是空格(整数情况))
               Mfornum2 = gettheM(num2);        //"2'4/21 "
               Nfornum2 = gettheN(num2, Mfornum2);    //" 89"
               theN = Nfornum1*Nfornum2;
               theM = Mfornum1*Mfornum2;
               if(theN>theM){
                   j=Euclid(theN,theM);
                   carrier1 = theN/theM;
                   }
               else
                   j=Euclid(theM,theN);
               theN/=j;
               theM/=j;
               if(theN%theM==0){
                   theN = theN/theM;
                   temp.append(Integer.toString(theN));
               }
               else{
                   if(carrier1!=0){                //判断该分数是不是假分数,是就转成带分数形式      
                       theN=(theN%theM);
                       temp.append(carrier1);
                       temp.append("'");
                       }
                   temp.append(Integer.toString(theN));
                   temp.append("/");
                   temp.append(Integer.toString(theM));
               }
               return temp.toString();
           }
           else if (processor.equals("÷")){
               Mfornum1 = gettheM(num1);        //确定加号前面的数字的分母值(此处要保证该数字的最后一位元素是空格)
               Nfornum1 = gettheN(num1, Mfornum1);    //确定加号后面的数字的分子值(此处要保证该数字的0号元素为数字,最后一位是空格(整数情况))
               Mfornum2 = gettheM(num2);        //"2'4/21 "
               Nfornum2 = gettheN(num2, Mfornum2);    //" 89"
               theN = Nfornum1*Mfornum2;
               theM = Mfornum1*Nfornum2;    
               if(theN>theM){
                   j=Euclid(theN,theM);
                   carrier1 = theN/theM;
                   }
               else        j=Euclid(theM,theN);
               theN/=j;
               theM/=j;
               if(theN%theM==0){
                   theN = theN/theM;
                   temp.append(Integer.toString(theN));
               }
               else{
                   if(carrier1!=0){                //判断该分数是不是假分数,是就转成带分数形式      
                       theN=(theN%theM);
                       temp.append(carrier1);
                       temp.append("'");
                       }
                   temp.append(Integer.toString(theN));
                   temp.append("/");
                   temp.append(Integer.toString(theM));//                   temp.append("\n");               }
           return temp.toString();
           }
           else return "运算符号没有规范传入";
       }
       /**
        * 算结果的分子分母方法
        */
       private int gettheN(String beforeM,int M){
           int theN = 0;
           int position1 = -1, position2 = -1;
           position1 = beforeM.indexOf("/");
           position2 = beforeM.indexOf("'");
           if(position1<0&&position2<0){
               try{
                   theN = theN + M * (Integer.parseInt(beforeM.substring(0)));
               }  catch (NumberFormatException  e)    {
                   e.printStackTrace();
               }
               return theN;
       }
           else if(position1>0&&position2<0){        
                   try{
                       theN += Integer.parseInt(beforeM.substring(0,position1));
                   }  catch (NumberFormatException  e)    {
                       e.printStackTrace();
                   }
                   return theN;
           }
           else if(position1>0&&position2>0){
               try{
                   theN = theN + M * (Integer.parseInt(beforeM.substring(0,position2)));
               }  catch (NumberFormatException  e)    {
                   e.printStackTrace();
               }
               try{
                   theN += Integer.parseInt(beforeM.substring(position2+1,position1));
               }  catch (NumberFormatException  e)    {
                   e.printStackTrace();
               }
               return theN;
       }
           else return -1;
       }
 
       private int gettheM(String afterN){
           int theM = 0;
           int position2  = -1;
           position2 = afterN.indexOf("/");
           int thezero = 0;
           if(position2>0){
                   try{
                       theM = Integer.parseInt(afterN.substring(position2+1));
                   }  catch (NumberFormatException  e)    {
                       e.printStackTrace();
                   }
           }
           else {
           theM=1;
           }
           return theM;
       }       
     
       private  int Euclid(int m,int n){
        while(n!=0){
            int r;
            r=m%n;
            m=n;
            n=r;
            Euclid(m,n);
            }
        return m;
        }

5.用于生成运算式的子运算顺序式(格式:+ab(a>b))存进StringBuilder类并返回

public class CheckOut {
     StringBuilder checkOut(String a,String b,String operator) {
         int aNum=0;
         int bNum=0;
         StringBuilder SB=new StringBuilder();
         //判断a,b分别是什么类型的数字
         int[] ajudge=judgeNum(a);
         int[] bjudge=judgeNum(b);
              //比较a,b的大小
         if(ajudge[0]*bjudge[1]>bjudge[0]*ajudge[1]) {
             //存进StringBuilder的顺序             SB.append(operator).append(a).append(b);
         }else {
             SB.append(operator).append(b).append(a);
         }
        return SB;    
            
     }
     
 private int[] judgeNum(String str) {
         int position1=-1;
         int position2=-1;
         int[] Array = new int[3];//存分子分母         
        
         
         position1 = str.indexOf("/");
         position2 = str.indexOf("'");
         if(position1<0&&position2<0){//整数
             Array[0]=Integer.valueOf(str);
             Array[1]=1;
         }
         
         if((position1>0&&position2>0)||(position1>0&&position2<0)){//带分数或分数
             String str1[]=str.split("\\'|\\/");
            int[] sons = new int[str.length()];
             for(int i=0;i<str1.length;i++) {
                 sons[i]=Integer.parseInt(str1[i]);                 
                }
            if(str1.length==3) {
                Array[0]=sons[0]*sons[3]+sons[2];
                Array[1]=sons[3];
            }else {                     
                Array[0]=sons[0];
                Array[1]=sons[1];
            }
         }
        return Array;         
     } 
     
}
六、测试运行

    测试用例1:题目个数num<=0或数字上限值<=1 结果:报错

    测试用例2:数目个数num=1000,正常的数字上限    结果:程序执行由3到5秒钟不等

    测试用例3:生成的答案文件或者成绩文件在指定目录存在同名同类型文件  结果:清除源文件信息,每次程序运行都更新文件信息

    测试用例4:生成100道式子,检查运算符个数的分布情况。结果:分布均匀

    测试用例5:生成100道式子,检查括号的分布情况。结果:分布均匀

    测试用例6:生成100道式子,检查不同数字类型的分布情况。结果:分布均匀

    测试用例7:特别地生成两个重复的式子,并进行查重   结果:查重成功,并成功删掉其一

    测试用例8:用户输入答案时输入特殊字符,结果:报错,错题+1

    测试用例9:用户只输入部分答案  结果:错题与对题统计无误

    测试用例10:正常生成式子与答案  结果:答案匹配

八、项目小结

我的结对对象是梁迪希同学
做得好的方面:在程序刚开始的时候,我还没有什么头绪,迪希同学先有思路,然后共同讨论了查重这部分的实现方法,之后的两天时间里我们都是分开做,各有各自的思路,我的思路也清晰了,考虑到需要生成不同的式子类型,应该去怎么实现。到晚上的时候,我们也会交流各自的想法。迪希同学在功能的实现方面的想法是要比我多的,在我某些地方卡住的时候会分享他的想法给我,这是值得我学习的地方。
做得不好的方面:在做项目的后段时间,由于时间的紧迫,我们各自分开实现不同的功能,但由于没能及时交流,使得功能之间没法很好地契合,所以花费了不少时间修整代码。往后在做类似团队项目时,要多交流,明确好分工,各自想法的优劣和各自项目功能的实现谁来做等。

结对编程作业(java)的更多相关文章

  1. UI-12组结对编程作业总结

    UI-12组结对编程作业总结 源码Github地址 https://github.com/tilmto/TILMTO/tree/master/Arithmetic 作业摘要 本次结对编程作业分为以下两 ...

  2. 【BUAA软工】结对编程作业

    项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程结对编程项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法,锻炼开发能力 作业目标 完 ...

  3. 11061160_11061151_Pair Project: Elevator Scheduler软件工程结对编程作业总结

    软件工程结对编程作业总结 11061160  顾泽鹏 11061151  庞梦劼 一.关于结对编程 这次的软工任务既不是单打独斗的个人任务,也不是集思广益的团队项目,而是人数为两人的结对编程.两个人合 ...

  4. 结对编程作业——四则运算GUI程序

    毛忠庆 201421122088 赵嘉楠 201421122065 源代码存放位置:https://gitee.com/ouwen0819/SiZeYunSuan.git 题目描述 使用 -n 参数控 ...

  5. C#【结对编程作业】小学数学习题助手

    一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...

  6. 关于软件工程结对编程作业 PairProject : Elevator Scheduler(电梯调度算法的实现与测试)的总结

    1)结对编程队友 1106xxxx 张扬 1106xxxx 杨军 其中,此项目的编程实现主要由前者完成. 2)关于结对编程 结对编程的优点: 最直接的一点:在结对编程中,由于有另一个人在你身边和你配合 ...

  7. 结对编程四则运算--JAVA实现(徐静、林文敏)

    Github项目地址 项目相关要求 -n 参数控制生成题目的个数 (√) Myapp.exe -n 10 // 将生成10个题目 -r 参数控制题目中数值(自然数.真分数和真分数分母)的范围 (√) ...

  8. 结对编程作业(python实现)

    一.Github项目地址:https://github.com/asswecanfat/git_place/tree/master/oper_make 二.PSP2.1表格: PSP2.1 Perso ...

  9. ASE code search -- 第二次结对编程作业

    baseline 复现 baseline模型 我们再这次实验中选择了deep code search方法作为了解并复现.下面介绍一下这两种方法 deep code search 模型的结构在论文中已经 ...

随机推荐

  1. BayaiM__经典SQL语句大全

    BayaiM__经典SQL语句大全 原创 作者:bayaim 时间:2016-06-16 09:22:24 32 0删除编辑 以下这篇文章,是一个垃圾,垃圾中的垃圾 ----------------- ...

  2. 4. 海思Hi3519A MPP从入门到精通(四 视频输出)

    VO(Video Output,视频输出)模块主动从内存相应位置读取视频和图形数据,并通过相应的显示设备输出视频和图形. 1. 基本概念 3519A芯片支持的显示/回写设备.视频层和图形层见下表. 注 ...

  3. 【cf375】D. Tree and Queries(dsu on tree+线段树)

    传送门 题意: 给出一颗以\(1\)为根的有根树,每个结点有个颜色\(c_i\). 之后要回答\(m\)组询问,每组询问包含\(v_i,k_i\),要回答以\(v_i\)为根的子树中,颜色出现次数不小 ...

  4. c# 第37节 接口的实现与继承

    本节内容: 1:接口继承注意 2:开发封闭原则: 3:实例解释接口的作用 1:接口继承注意 接口的继承: :类继承具有单根性,接口可多重继承: :接口继承多个接口的时候,派生接口名与父接口用冒号隔开, ...

  5. [C1] Andrew Ng - AI For Everyone

    About this Course AI is not only for engineers. If you want your organization to become better at us ...

  6. CF1252J Tiling Terrace

    CF1252J Tiling Terrace 洛谷评测传送门 题目描述 Talia has just bought an abandoned house in the outskirt of Jaka ...

  7. 执行flutter doctor后,无任何反应

    flutter运行需要联网,并且由于qiang,会导致访问缓慢,解决办法 export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_ ...

  8. <Binary Search> 81 (高频)34 (很难hard, 高频)315 (hard)354

    81. Search in Rotated Sorted Array II 如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的.而如果可以有重复值,就会出现来面两种情 ...

  9. 小程序-tabBar简易版

    <!-- 结构 --> <view class="wrapper"> <block wx:for="{{desc}}"> & ...

  10. SpringCloud微服务常见组件理解

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...