结对对象:许峰铭

一.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. [b0036] python 归纳 (二一)_多进程数据共享和同步_服务进程Manager

    # -*- coding: utf-8 -*- """ 多进程数据共享 服务器进程 multiprocessing.Manager 入门使用 逻辑: 20个子线程修改共享 ...

  2. ubuntu中输入arm-linux-gcc -v出现no such file or directory

    这个问题困扰了我差不多两天时间了,明明已经安装了arm-linux-gcc,且系统变量和用户变量都配置好了 但每次输入arm-linux-gcc -v都会出现如题所示错误.最终经过查到一个帖子有说是因 ...

  3. opencv 截取任意四边形区域的图像

    截取任意四边形区域的图像. mask就是结果. 需要定义四边形区域,分别是 tl, tr, bl, br std::map<int, std::set<int>> genera ...

  4. Centos7防火墙添加端口

    添加 firewall-cmd --zone=public --add-port=80/tcp --permanent   (--permanent永久生效,没有此参数重启后失效) 重新载入 fire ...

  5. javaagent的实现

    实现javaagent功能的是一个叫做instrument的JVMTIAgent(linux下对应的动态库是libinstrument.so),另外instrument agent还有个别名叫JPLI ...

  6. 【2019.8.11上午 慈溪模拟赛 T2】十七公斤重的文明(seventeen)(奇偶性讨论+动态规划)

    题意转化 考虑我们对于集合中每一个\(i\),若\(i-2,i+k\)存在,就向其连边. 那么,一个合法的集合就需要满足,不会存在环. 这样问题转化到了图上,就变得具体了许多,也就更容易考虑.求解了. ...

  7. jquery模拟点击事件

    在某些情况下,我们需要自动执行一些点击事件.比如:一些 tab 一般是通过点击事件来加载不同的数据内容. 而如果要页面加载完直接显示第三个 tab,怎么办呢?此时就需要用到 jQuery 的模拟点击事 ...

  8. 第02组 Beta冲刺(5/5)

    队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 验收了小程序的主要功能 制作Beta展示所需要用到的视频 制作Beta展示PPT 准备Beta答辩 提交记录(全组共用) ...

  9. 【Java并发专题之二】Java线程基础

    使用线程更好的提高资源利用率,但也会带来上下文切换的消耗,频繁的内核态和用户态的切换消耗,如果代码设计不好,可能弊大于利. 一.线程 进程是分配资源的最小单位,线程是程序执行的最小单位:线程是依附于进 ...

  10. JDBC数据库连接测试工具

    贴代码 import java.io.PrintStream; import java.sql.*; import java.util.Properties; public class ZJdbcPi ...