zoukankan      html  css  js  c++  java
  • 结对项目——自动生成小学四则运算题目

    1.Github项目地址:https://github.com/13202008832/FourArithmetic

    作者:陈惠霖  3118005088

         侯晓龙  3118005091

    2.PSP表格(时间评估)

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

    3.效能分析

     出现问题:因为我们使用的是栈操作,不同类型的经常要调用函数进行转变,又重新转换回去

     解决方案:全部转换为同一类型操作,减少类型转变

     消耗最大函数:表达式生成函数

    void Exp(stack S,int I) {
            //提取符号
            String f = new String();
            f = S.pop();
            //定义优先等级
            int i;
            if (f == "+" || f == "-")
                i = 1;
            else i = 2;
            //提取右表达式
            stack b = new stack(7);
            {
                int m = 0, n = 0;
                while(true) {
                    String x = S.pop();
                    if (x == "+" || x == "-" || x == "×" || x == "÷")
                        n++;
                    else 
                        m++;
                    b.push(x);
                    if(1 == m - n)
                        break;
                }
                b.inversion();
            }
            //提取左表达式
            stack a = new stack(7);    
            while(true) {
                String x = S.pop();
                a.push(x);
                if(S.isEmpty()) break;
            }
            a.inversion();
            //表达式输出
            if(i < I)
                Y = Y + "(";
            if(a.top == 0)
                Y = Y + a.pop();
            else Exp(a,i);
            Y = Y + " "+f+" ";
            if(b.top == 0)
                Y = Y + b.pop();
            else Exp(b,i+1);
            if(i < I)
                Y = Y + ")";
            if(I == 0) Y = Y + " = ";
        }

    4.设计实现过程

       通过对题目的分析,我们发现对于分数和整数的表示都可以用分数来表示,于是我们创建了一个Fraction的实体类,并使用Method包下的Rando类中的getFraction(intmax)方法随机获得一个String类型的分数,和getOperator()方法来获取一个随机的操作符,对于表达式的生成,我们采用了逆波兰表达式,并用Entity包下的stack类存储和Method包下的rpn类排序入栈,answer类来实现表达式答案的获取,而对于实现四则运算的加减乘除,我们在Method包下建立了OpFraction类,用 opFr(String m,String op, String n) 方法实现,最后,我们采用的是建立JavaWeb项目来完成这个结对项目,用户可以在jsp建立的页面上控制题目数量和数值范围,再在D盘中3个txt文件中查看题目、答案、答题情况。

    5.代码说明

     Fraction实体类代码

    package Entity;
    
    import Method.OpFraction;
    
    public class Fraction {
    
        private int fson;   //分子m
        private int fma;   //分母n
        private String fract;  //分数m/n
        private String daiFract; //带分数i'm/n
        private int dai;  //i
        
        public int getDai() {
            return dai;
        }
        public void setDai(int dai) {
            this.dai = dai;
        }
        public String getDaiFract() {
            return daiFract;
        }
        public void setDaiFract(int i,int m,int n) {
            this.dai=i;
            this.fma=n;
            this.fson=m;
            this.daiFract = String.valueOf(i)+"'"+String.valueOf(m)+"/"+String.valueOf(n);;
        }
        public int getFson() {
            return fson;
        }
        public void setFson(int fson) {
            this.fson = fson;
        }
        public int getFma() {
            return fma;
        }
        public void setFma(int fma) {
            this.fma = fma;
        }
        public String getFract() {
            return fract;
        }
        public void setFract(int m,int n) {
            this.fma=n;
            this.fson=m;
            this.fract = String.valueOf(m)+"/"+String.valueOf(n);
        }
        public String tranFr(Fraction q) {
            int max;
            OpFraction o=new OpFraction();
            
            if(q.fson==0) {return "0";}else {
            max=o.maxNum(q.fma,q.fson);
            q.setDaiFract(q.dai, q.fson/max, q.fma/max);
            if(q.dai==0) {
                if(q.fma==1) {
                    return String.valueOf(q.fson);                
                }
                else{
                
                 return String.valueOf(q.fson)+"/"+String.valueOf(q.fma);
            }}
            else {
                if(q.fma==1) {
                    return String.valueOf(q.fson);                
                }
                else return String.valueOf(q.dai)+"'"+String.valueOf(q.fson)+"/"+String.valueOf(q.fma);
            }
        }}
        
        
        
        public double val(Fraction f) {
        
            if(f.fson==0)return 0;
            return f.dai+f.fson/f.fma;
        }
        
            
    }

    getFraction(intmax)方法随机获得一个String类型的分数

        public String getFraction(double max) {
            int dai,son,ma;
            Fraction f=new Fraction();
            do {
                dai=getNumber((int) max);
                son=getNumber((int) max);
                ma=getNumber((int) max);
                for(;ma==0;)
                    ma=getNumber((int) max);
                f.setDaiFract(dai, son, ma);
            }while(!(f.val(f)<max)||ma==0||son>ma);
            return f.tranFr(f);
        
        }

     tranFr(Fraction f)将Fraction转换为String形式

        public String tranFr(Fraction q) {
            int max;
            OpFraction o=new OpFraction();
            
            if(q.fson==0) {return "0";}else {
            max=o.maxNum(q.fma,q.fson);
            q.setDaiFract(q.dai, q.fson/max, q.fma/max);
            if(q.dai==0) {
                if(q.fma==1) {
                    return String.valueOf(q.fson);                
                }
                else{
                
                 return String.valueOf(q.fson)+"/"+String.valueOf(q.fma);
            }}
            else {
                if(q.fma==1) {
                    return String.valueOf(q.fson);                
                }
                else return String.valueOf(q.dai)+"'"+String.valueOf(q.fson)+"/"+String.valueOf(q.fma);
            }
        }}

    tranString(String str)将String类型用Fraction存储

    Fraction tranString(String str) {
            Fraction f=new Fraction();
            if(str.indexOf("'")>=0) {
            String[] s1=str.split("'");
            
            String[] s2=s1[1].split("/");
            f.setDaiFract(Integer.parseInt(s1[0]),Integer.parseInt(s2[0]), Integer.parseInt(s2[1]));
            }
            else {
                if(str.indexOf("/")>=0) {
                    String[] s1=str.split("/");
                    f.setDaiFract(0,Integer.parseInt(s1[0]), Integer.parseInt(s1[1]));
                }
                else {
                    
                    f.setDaiFract(0,Integer.parseInt(str),1);
                    
                }
            }
            return f;
            
        }

    rpn类实现将生成的数和操作符组成随机逆波兰表达式的功能

    public class rpn {
        public stack Y = new stack(7);;
        
        public void r(int max) {
            Rando f=new Rando();
            
            Y.push(f.getFraction(max));
            Y.push(f.getFraction(max));
            int m = 0,n = 0,i = (int)(Math.random()*3);//均等生成0、1、2
            while(m < i && n < i) {
                int j = (int)(Math.random()*2);
                if(j == 0 || n-m>0) {Y.push(f.getFraction(max));m++;}
                    else {Y.push(f.getOperator());n++;}
            }
            while(m == i && n < i) {
                Y.push(f.getOperator());n++;
            }
            while(n == i && m < i) {
                Y.push(f.getFraction(max));m++;
            }        
            Y.push(f.getOperator());
            
        }
    }

    expression类实现了转换逆波兰表达式为标准表达式的功能

    public class expression {
        public String Y = new String();
        public stack as;
        
        public expression(stack As) {
            this.as=As;
            }
        
        void Exp(stack S,int I) {
            //提取符号
            String f = new String();
            f = S.pop();
            //定义优先等级
            int i;
            if (f == "+" || f == "-")
                i = 1;
            else i = 2;
            //提取右表达式
            stack b = new stack(7);
            {
                int m = 0, n = 0;
                while(true) {
                    String x = S.pop();
                    if (x == "+" || x == "-" || x == "×" || x == "÷")
                        n++;
                    else 
                        m++;
                    b.push(x);
                    if(1 == m - n)
                        break;
                }
                b.inversion();
            }
            //提取左表达式
            stack a = new stack(7);    
            while(true) {
                String x = S.pop();
                a.push(x);
                if(S.isEmpty()) break;
            }
            a.inversion();
            //表达式输出
            if(i < I)
                Y = Y + "(";
            if(a.top == 0)
                Y = Y + a.pop();
            else Exp(a,i);
            Y = Y + " "+f+" ";
            if(b.top == 0)
                Y = Y + b.pop();
            else Exp(b,i+1);
            if(i < I)
                Y = Y + ")";
            if(I == 0) Y = Y + " = ";
        }
        public void exp() {
            Exp(as,0);
        }
    }

    answer类实现获取生成好的表达式的答案的功能

    public class anwser {
         public String Y = new String();
         public stack as;
         public boolean flag = true;
         
         public anwser(stack As) {
          this.as=As;
             }
         
         public void anw(){
          stack p = new stack(7);
          while(as.top>0) {
           String a = new String();
           String b = new String();
           String f = new String();
           f = as.pop();
           int i = 0;
           //得出一组fab
           while(true) {
            String x;
            x = as.pop();
            if (x == "+" || x == "-" || x == "×" || x == "÷") {
             p.push(f);
             if(i == 1)
              p.push(a);
             f = x;
             i = 0;
            }
            else if(i == 0) {
             a = x;
             i++;
            }
            else {
             b = x;
             i++;
            }
            if(i == 2)break;
           }
           String y = new String();
           OpFraction op=new OpFraction();
           y = op.opFr(b,f,a);
           if(y=="-1")flag=false;
           as.push(y);
           while(!p.isEmpty()) {
            as.push(p.pop());
           }
          }
          Y = as.pop();
         }
    }

    DaoTxt类实现了将String类型数据写入txt的相关功能

    package Method;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class DaoTxt {
        private static String answerPath = "D:\answerfile.txt";
        private static String correctPath = "D:\Grade.txt";
        private static String tiPath = "D:\exercisefile.txt";
        private static void saveAsFileWriter(String content,String path) {
            FileWriter fwriter = null;
            try {
                // true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
                fwriter = new FileWriter(path, true);
                fwriter.write(content);
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    fwriter.flush();
                    fwriter.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        public void clear(String path) {
            FileWriter fwriter = null;
            try {
                // true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
                fwriter = new FileWriter(path, false);
                fwriter.write("
    ");
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    fwriter.flush();
                    fwriter.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        public void saveAnswer(String content) {
            saveAsFileWriter(content,answerPath);
        }
        public void saveGrade(String content) {
            saveAsFileWriter(content,correctPath);
        }
        public void saveExercise(String content) {
            saveAsFileWriter(content,tiPath);
        }
        public void clearAll() {
            clear(answerPath);
            clear(correctPath);
            clear(tiPath);
        }
    }

    6.测试说明

     首先在eclipse中启动Tomcat服务(2000与10皆可自己输入)

     

    点击确定,生成题目

    点击提交

     

    exercisefile.txt中存放了生成的所有题目

    answerfile.txt中存入了所有题目以及答案

    Grade.txt中存储了答题情况

     

    7.PSP表格(实际耗费时间)

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

    合计

    920 960

    8.项目小结

     项目总结:本次结对作业进行基本顺利,我们各自负责着自己的模块,虽然线上讨论减少了一些比较明确的沟通,但是通过对方的介绍跟对各自代码的微调,如特定函数的使用说明、格式的规定(我们最终统一将数字和符号改为String类型),使得我们最终顺利对接成功,经过统一整理后才做出这次项目。因此,对于结对项目,我们有以下观点:

    • 合理分配工作,各自选择自己擅长的模块
    • 确定好对接方式,有相应的函数调用说明
    • 找出问题所在,积极与对面沟通解决方案

     结对感受:陈惠霖:侯晓龙是个非常不错的伙伴,他帮我解决了很多我不擅长的模块,提供了我很多函数的调用,也很少有bug的存在,给予了我很多帮助,非常给力!

          侯晓龙:两个人一起合作感觉还不错,只需要自己完成一部分,所以工作时压力不是很大,很多问题经过讨论就会迎刃而解,队友陈惠霖给了我很多帮助,感觉非常不错。

  • 相关阅读:
    Single Threaded Execution
    多线程(第三天)
    多线程(第二天)
    IE中float:right单独一行
    web.xml配置
    java调用asmx的webservice
    跨域访问
    jsp页面导入jstl标签
    搜索dwr做即时聊天的时候看到的问题
    LigerUI tree在ie下显示不出来/LigerUI 控件在ie下错乱
  • 原文地址:https://www.cnblogs.com/arietischl/p/12615771.html
Copyright © 2011-2022 走看看