zoukankan      html  css  js  c++  java
  • 软件工程网络15结对编程作业

    一、结对编程

    二、需求分析

    1、原项目分析

    1.1项目类图

    1.2存在的不足

    • 变量的命名使用abc,不够规范。a既然表示操作符可以改名为oprator。

    • 运行该程序,初次选择计算题数并进行计算,程序会将错题存在错题集中。之后所有的计算练习是在错题集中抽取。需要重新运行该程序才能选择新的题目进行练习。
    • 复习错题选择的题数若超过错题集题数,未提示错误。
    • 在做题界面中点击开始后修改计时时间,计时器停止运行,最后做题显示时间为手动修改的时间。
    • 在做题界面点击开始后,再次点击开始,计时器重新计时。
    • 错题集的题目根据每次做题的情况依次累加。若某题错误率高,随机选题复习的话很有可能选的题目都是该题,显得累赘。

    1.3原项目测试用例

    • (以整数和分数的乘法为例)原项目的单元测试分别对整数和分数的加减乘除进行测试,每个测试用了五个用例。

    2、改进分析

    2.1改善部分

    • 修改的代码中加入多操作符的运算
    • 加入支持括号优先级运算
    • 对表达式进行去重

    2.2思维导图

    2.3支持括号优先级运算

    2.4算式去重

    • 暂时还没实现,但是写的算法大概如下:
     int Isomorphic(Tree t1,Tree t2){
    	 if((t1==NULL)&&(t2==NULL))return 1;//都为空
    	 if(((t1==NULL)&&(t2!=NULL))||((t1!=NULL)&&(t2==NULL))) return 0;//一个为空另一个不为空
    	 if(t1->root!=t2->root) return 0;//根节点的值不一样
    	 if((t1->lchild==NULL)&&(t2->lchild==NULL)) return Isomorphic(t1->lchild,t2->rchild);
    	 if(((t1->lchild!=NULL)&&(t2->lchild!=NULL))&&(t1->lchild->data==t2->lchild->data))//没有交换
    		 return (Isomorphic(t1->lchild,t2->lchild)&&Isomorphic(t1->rchild,t2->rchild));//如果两个都不为空且左儿子相等,应该递归的找左对应左,右对应右
    	 else
    		 return (Isomorphic(t1->lchild,t2->rchild)&&Isomorphic(t1->rchild,t2->lchild));//否则就是交换了,递归的判断左对应右,右对应左
    
     };
    

    2.5测试用例

    • 新功能测试用例

    3、PSP表格

    PSP2.1 个人开发流程 预估耗费时间(分钟) 实际耗费时间(分钟)
    Planning 计划 8 15
    ·Estimate 明确需求和其他相关因素,估计每个阶段的时间成本 8 6
    Development 开发 240 284
    ·Analysis 需求分析 (包括学习新技术) 6 10
    ·Design Spec 生成设计文档 5 10
    ·Design Review 设计复审 4 15
    ·Coding Standard 代码规范 5 10
    ·Design 具体设计 20 30
    ·Coding 具体编码 288 300
    ·Code Review 代码复审 20 30
    ·Test 测试(自我测试,修改代码,提交修改) 15 25
    Reporting 报告 9 10
    · 测试报告 3 5
    · 计算工作量 2 1
    · 并提出过程改进计划 3 3

    4、附加题

    4.1支持乘方运算

    三、代码展示

    BinaryTree类//构建二叉树
    import java.util.ArrayList;
    
    public class BinaryTree   
    {  
          
        private TreeNode root;  
        private int num;  
        private ArrayList<TreeNode> opeList = new ArrayList<TreeNode>();  
          
        public BinaryTree(int num){  
            this.num = num;  
        }  
          
        public int getNum(){  
            return num;  
        }  
          
        public void setNum(int num){  
            this.num = num;  
        }  
          
        public void setTreeNode(TreeNode root){  
            this.root = root;  
        }  
          
          
        /** 
         * 获取最终的表达式,必须在CalAndVal()方法后调用 
         *  
         * @return str 
         */  
        public String toString(){  
            String str = root.toString();  
            str = str.substring(1, str.length()-1);  
            return str;  
        }  
          
        /** 
         * 计算并验证表达式 
         *  
         * @return result 
         */  
        public String CalAndVal(){  
            return root.getResult();  
        }  
          
        /** 
         * 计算二叉树的深度(层数)  
         *  
         * @return deep 
         */  
        public int getDeep(){  
            int i = this.num;  
            int deep = 2;  
            while(i/2 > 0){  
                deep++;  
                i /= 2;  
            }  
            return deep;  
        }  
          
        /** 
         * 生成二叉树 
         *  
         */  
        public void createBTree(){  
            TreeNode lchild, rchild, lnode, rnode;  
            int ran= Ran.getNumber(2),x,y;
            if(num == 1){
            	if(ran==0){
            		lchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);  
                    rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);  
            	}
            	else{
            		x=Ran.getNumber(9)+1;
            		y=Ran.getNumber(20)+1;
            		for(int j=0;y<=x;j++){
            			y=Ran.getNumber(20)+1;
            		}
            		lchild = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
            		x=Ran.getNumber(9)+1;
            		y=Ran.getNumber(20)+1;
            		for(int j=0;y<=x;j++){
            			y=Ran.getNumber(20)+1;
            		}
                    rchild = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
            	}
                root = new TreeNode(String.valueOf(Ran.getOperator()), lchild, rchild);  
            }  
            else{  
                int num1 = 0;  
                int n = getDeep() - 3;  
                boolean[] place = Ran.getChildPlace(num);  
                root = new TreeNode(String.valueOf(Ran.getOperator()), null, null);  
                opeList.add(root);  
                for(int i = 0; i < n; i++){  
                    for(int j = 0; j < (int)Math.pow(2, i); j++, num1++){  
                        lchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);  
                        rchild = new TreeNode(String.valueOf(Ran.getOperator()), null, null);  
                        opeList.get(j + num1).setChild(lchild, rchild);  
                        opeList.add(lchild);  
                        opeList.add(rchild);  
                    }  
                }  
                for(int i = 0; i < place.length; i++){  
                    if(place[i]){  
                    	if(ran==0){
                    		lnode = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);  
                            rnode = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);  
                    	}
                    	else{
                    		x=Ran.getNumber(9)+1;
                    		y=Ran.getNumber(20)+1;
                    		for(int j=0;y<=x;j++){
                    			y=Ran.getNumber(20)+1;
                    		}
                    		lnode = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
                    		x=Ran.getNumber(9)+1;
                    		y=Ran.getNumber(20)+1;
                    		for(int j=0;y<=x;j++){
                    			y=Ran.getNumber(20)+1;
                    		}
                            rnode = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
                    	}
                        if(i%2 == 0){  
                            lchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);  
                            opeList.add(lchild);  
                            opeList.get(num1).setLchild(lchild);  
                        }  
                        else{  
                            rchild = new TreeNode(String.valueOf(Ran.getOperator()), lnode, rnode);  
                            opeList.add(rchild);  
                            opeList.get(num1).setRchild(rchild);  
                        }  
                    }  
                    else{  
                        if(i%2 == 0){  
                        	if(ran==0){
                        		lchild=new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);         
                        	}
                        	else{
                        		x=Ran.getNumber(9)+1;
                        		y=Ran.getNumber(20)+1;
                        		for(int j=0;y<=x;j++){
                        			y=Ran.getNumber(20)+1;
                        		}
                        		lchild = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
                        	}  
                            opeList.get(num1).setLchild(lchild);  
                        }  
                        else{  
                    
                             	if(ran==0){
                             		rchild = new TreeNode(String.valueOf(Ran.getNumber(10)), null, null);          
                             	}
                             	else{
                             		x=Ran.getNumber(9)+1;
                             		y=Ran.getNumber(20)+1;
                             		for(int j=0;y<=x;j++){
                             			y=Ran.getNumber(20)+1;
                             		}
                             		rchild = new TreeNode(String.valueOf(x)+"/"+String.valueOf(y), null, null); 
                             	}  
                            opeList.get(num1).setRchild(rchild);  
                        	 
                        }  
                    num1 = num1 + i%2;  
                }  
            }  
        }  
    }  
    }
    
    TreeNode类//树节点类,并进行递归计算
    public class TreeNode {  
          
        private String str;  
        private TreeNode rchild = null;  
        private TreeNode lchild = null;  
          
        public TreeNode(String str){  
            this.str = str;  
        }  
          
        public TreeNode(String str, TreeNode lchild, TreeNode rchild){  
            this.str = str;  
            this.rchild = rchild;  
            this.lchild = lchild;  
        }  
          
        public void setChild(TreeNode lchild, TreeNode rchild){  
            this.lchild = lchild;  
            this.rchild = rchild;  
        }  
          
        public TreeNode getRchild() {    
            return rchild;    
        }    
        public void setRchild(TreeNode rchild) {    
            this.rchild = rchild;    
        }    
        public TreeNode getLchild() {    
            return lchild;    
        }    
        public void setLchild(TreeNode lchild) {    
            this.lchild = lchild;    
        }  
          
        public String getStr(){  
            return str;  
        }  
          
        /** 
         * 获取每个节点的运算结果,并检验除法 
         * 1)除数为0 
         * 2)不能整除 //不考虑,允许分数的出现
         * 出现以上两种情况的话将该运算符转换成其他三种运算符 
         *  
         * @return result 
         */  
        public String getResult(){  
        	Compute com=new Compute();
            if(hasChild()){  
                switch(str){  
                    case "+":
                    	if(!getLchild().getResult().contains("/"))
                    		return String.valueOf(Integer.parseInt(getLchild().getResult()) + Integer.parseInt(getRchild().getResult())); 
                    	else
                    		return com.Add(getLchild().getResult(),getRchild().getResult());
                    case "-":  
                    	if(!getLchild().getResult().contains("/"))
                        	return String.valueOf(Integer.parseInt(getLchild().getResult()) - Integer.parseInt(getRchild().getResult()));  
                    	else
                    		return com.Subtract(getLchild().getResult(),getRchild().getResult());
                    case "*":  
                    	if(!getLchild().getResult().contains("/"))
                        	return String.valueOf(Integer.parseInt(getLchild().getResult()) * Integer.parseInt(getRchild().getResult()));  
                    	else	
                    		return com.Multiply(getLchild().getResult(),getRchild().getResult());
                    case "÷":  
                        if(getRchild().getResult().equals("0")||getRchild().getResult().contains("0/")){  
                            while(str.equals("÷")){  
                                str = String.valueOf(Ran.getOperator());  
                            }  
                            return this.getResult();  
                        }   
                  
                        else{
                        	if(!getLchild().getResult().contains("/")){
                        		if(Integer.parseInt(getLchild().getResult()) % Integer.parseInt(getRchild().getResult()) != 0){  
                                    while(str.equals("÷")){  
                                        str = String.valueOf(Ran.getOperator());  
                                    }  
                                    return this.getResult();  
                                }
                        		else 
                        			return String.valueOf(Integer.parseInt(getLchild().getResult()) / Integer.parseInt(getRchild().getResult())); 
                        	}
                        		
                        	else{
                        		
                        		return com.Divide(getLchild().getResult(),getRchild().getResult());
                        	}
                        		
                        }
                    case "^":
                    	if(!getLchild().getResult().contains("/")){
                    		if(Math.pow(Double.parseDouble(getLchild().getResult()),Double.parseDouble(getRchild().getResult()))<1){
                    			while(str.equals("^")){  
                                    str = String.valueOf(Ran.getOperator());  
                                }  
                                return this.getResult();
                    		}
                    		else
                    			return String.valueOf((new Double (Math.pow(Double.parseDouble(getLchild().getResult()),Double.parseDouble(getRchild().getResult())))).intValue()); 
                    	}
                    		
                    	else{
                    		while(str.equals("^")){  
                                str = String.valueOf(Ran.getOperator());  
                            }  
                            return this.getResult();
                    	}
                    	
                    	
                            
                }  
            }  
            return str;  
        }       
          
        /** 
         * 先对每个运算式添加括号,然后根据去括号法则,去掉多余的子式的括号 
         *  
         * @return string 
         */  
        public String toString(){  
            String Lstr = "", Rstr = "", Str = "";  
            if(hasChild()){  
                //右子树如果有孩子,说明右子树是一个表达式,而不是数字节点。  
                if(getRchild().hasChild()){                           
                    //判断左邻括号的运算符是否为'/'  
                    if(str.equals("÷")||str.equals("^")){  
                        //获取右子树的表达式,保留括号  
                        Rstr = getRchild().toString();                
                    }  
                    //判断左邻括号的运算符是否为'*'或'-'  
                    else if(str.equals("*") || str.equals("-")){  
                        //判断op是否为'+'或'-'  
                        if(getRchild().str.equals("+") || getRchild().str.equals("-")){   
                            Rstr = getRchild().toString();            
                        }  
                        else{  
                            //获取右子树的表达式,并且去括号   
                            Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);    
                        }  
                    }  
                    else{  
                        //右子树除此之外都是可以去括号的。  
                        Rstr = getRchild().toString().substring(1, getRchild().toString().length()-1);        
                    }  
                }  
                else{  
                    Rstr = getRchild().str;  
                }  
                //左子树的情况同右子树类似  
                if(getLchild().hasChild()){                                               
                    if(str.equals("*") || str.equals("÷")){  
                        if(getLchild().str.equals("+") || getLchild().str.equals("-")){  
                            Lstr = getLchild().toString();  
                        }  
                        else{  
                            Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);  
                        }  
                    }  
                    else{  
                        Lstr = getLchild().toString().substring(1, getLchild().toString().length()-1);  
                    }  
                }  
                else{  
                    Lstr = getLchild().str;  
                }  
                //获取当前的运算式,并加上括号  
                Str = "(" + Lstr + str + Rstr + ")";                                      
            }  
            else{  
                //若没有孩子,说明是数字节点,直接返回数字  
                Str = str;  
            }  
            return Str;  
        }  
          
        public boolean hasChild(){  
            if(lchild == null && rchild == null)  
                return false;  
            else  
                return true;  
        }  
    }  
    
    Compute类//对分数进行计算
    public class Compute {
    	
    	public String Add(String str1,String str2){
    		int mol1,mol2,den1,den2;
    		int mol,den;
    		mol1=Integer.parseInt(Trans(str1)[0]);
    		den1=Integer.parseInt(Trans(str1)[1]);
    		mol2=Integer.parseInt(Trans(str2)[0]);
    		den2=Integer.parseInt(Trans(str2)[1]);
    		mol=mol1*den2+mol2*den1;
    		den=den1*den2;
    		int gcd=Compute.GCD(mol,den);
    		mol/=gcd;
    		den/=gcd;
    		return(mol+"/"+den);
    	}
    	public String Subtract(String str1,String str2){
    		int mol1,mol2,den1,den2;
    		int mol,den;
    		mol1=Integer.parseInt(Trans(str1)[0]);
    		den1=Integer.parseInt(Trans(str1)[1]);
    		mol2=Integer.parseInt(Trans(str2)[0]);
    		den2=Integer.parseInt(Trans(str2)[1]);
    		mol=mol1*den2-mol2*den1;
    		den=den1*den2;
    		int gcd=Compute.GCD(mol,den);
    		mol/=gcd;
    		den/=gcd;
    		return(mol+"/"+den);
    	}
    	public String Multiply(String str1,String str2){
    		int mol1,mol2,den1,den2;
    		int mol,den;
    		mol1=Integer.parseInt(Trans(str1)[0]);
    		den1=Integer.parseInt(Trans(str1)[1]);
    		mol2=Integer.parseInt(Trans(str2)[0]);
    		den2=Integer.parseInt(Trans(str2)[1]);
    		mol=mol1*mol2;
    		den=den1*den2;
    		int gcd=Compute.GCD(mol,den);
    		mol/=gcd;
    		den/=gcd;
    		return(mol+"/"+den);
    	}
    	public String Divide(String str1,String str2){
    		int mol1,mol2,den1,den2;
    		int mol,den;
    		mol1=Integer.parseInt(Trans(str1)[0]);
    		den1=Integer.parseInt(Trans(str1)[1]);
    		mol2=Integer.parseInt(Trans(str2)[0]);
    		den2=Integer.parseInt(Trans(str2)[1]);
    		mol=mol1*den2;
    		den=den1*mol2;
    		int gcd=Compute.GCD(mol,den);
    		mol/=gcd;
    		den/=gcd;
    		return(mol+"/"+den);
    	}
    	public static String[] Trans(String str){
    		String[] strArray=new String[2];
    		for(int i=0;i<str.length();i++){
    			if(str.charAt(i)=='/'){
    				strArray[0]=str.substring(0,i);
    				strArray[1]=str.substring(i+1,str.length());
    				break;
    			}	
    		}
    		return strArray;
    	}
    	public static int GCD(int a,int b) {
            if(b==0)
                return a;
            else
                return GCD(b,a%b);
        }
    }
    
    
    QA_List类//输出界面根据题数调用式子及返回结果
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    public class QA_List {
    
    	public static int i;
    	public static List<String> Qusetion=new ArrayList<String>();
    	public static List<String> Answer=new ArrayList<String>();
    	public QA_List(){
    		for(int a=0;a<i;a++)
    	    {
    
    	        BinaryTree bTree;  
    
    	            bTree = new BinaryTree(2);//随机生成数与表达式的数字个数有关  
    	            bTree.createBTree();  
    	            String result = bTree.CalAndVal();
    	            if(result.contains("/")){
    	            	if(Compute.Trans(result)[0].equals("0")){
    	            		result="0";
    	            	}else if(Compute.Trans(result)[1].equals("1")){
    	            		result=Compute.Trans(result)[0];
    	            	}
    	            }
    	            Answer.add(result);
    	        	Qusetion.add(bTree.toString());
    	
    	    }
         for(int a=0;a<(10-i);a++){
         	Answer.add("");
         	Qusetion.add("");
         }
    	}
    	 
    }
    
    

    四、程序运行

    五、小结感受

    1、结对照片

    2、结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。

    • 我觉得结对编程确实有1+1>2的效果。编程过程有时候出现的bug怎么找都找不到,都说旁观者清,说不定在小伙伴的检查下能够有意想不到的收获;编程的整个算法思路能够有人一起沟通,可以择较优者进行编程,会事半功倍。遇到困难时,有个人能够互相勉励,还是挺不错的。

    3、码云提交记录截图


  • 相关阅读:
    vue项目index.html缓存
    vue刷新当前页面
    keep-alive
    JS刷算法题:二叉树
    CSS动效集锦,视觉魔法的碰撞与融合(三)
    算法:栈和队列题目集合(一)
    浅谈设计模式(二):装饰器模式|中介模式|原型模式
    聊聊JS的二进制家族:Blob、ArrayBuffer和Buffer
    浅谈设计模式(一):状态模式|外观模式|代理模式
    纵论WebAssembly,JS在性能逆境下召唤强援
  • 原文地址:https://www.cnblogs.com/qxx-Ultraman/p/8641943.html
Copyright © 2011-2022 走看看