软件工程第三次作业 结对编程

结对编程

小组成员:

201521123055 林一心 博客地址

201521123046 张杭镖 博客地址

项目地址

一、分析改进现有代码

1109682-20180325200542281-310965413.png

1109682-20180325200618346-1051169043.png

1.单元测试:

1109682-20180325200509613-965177584.png

2.覆盖率:

1109682-20180325200515875-1914315732.png

3.确定当前设计的一个弱点,通过重构,确保在这个地方已有测试覆盖并保证重构没有改变已有的功能:

原程序只能生成两个数之间的算式,并且分数与整数算式出现几率没设置正确。

4.修改代码后,检查代码覆盖,看单元测试是否需要修改?测试用例是否需要增加?

单元测试需要修改,因为添加了多个数字的运算。

二、功能扩展

增加了括号运算符,相应的计算函数也要添加括号运算符的处理,原代码把计算过程放在main生成算式的main类中处理,扩展功能后代码显得臃肿,因此单独把计算功能拉出来做一个Calculator类。(这个计算功能同样也支持多位整数的计算,以便小学生升级到进阶地狱)

核心代码:

生成题目

        
    public main()//生成四则运算并输出
    {
        new Thread(myTimeRunable).start();
        int n = 0;
        MainFrame ma= new MainFrame();


        try{
            //调用初始化方法
            jbInit();
        }
        catch(Exception exception){
            exception.printStackTrace();
        }

        try{

            n= Integer.parseInt(ma.number);

            }catch(NumberFormatException e){
                //利用消息对话框提示输入失败
                JOptionPane.showMessageDialog(this,"输入错误!请重新输入");
                }

            int m = (int)(Math.random()*n+1);//随机整数题目和分数题目的题量

            for(int j=0;j<(n-m);j++){//整数题目
                int no=(int)(Math.random()*3+1); //最多四个数字运算
                StringBuffer qustr=new StringBuffer("");
                String ans;
                int numm=(int)(Math.random()*9+1);//随机数字

                qustr.append(numm);

                for(int i=0;i<no;i++){
                    numm=(int)(Math.random()*9+1);
                    int op=(int)(Math.random()*4+1);//随机选择计算符

                    if(op==1){//加法
                        qustr.append("+"+numm);
                        //Answer.add(num1+num2+"");
                    }
                    if(op==2){
                        qustr.append("-"+numm);
                    }

                    if(op==3){//乘法
                        qustr.append("*"+numm);
                    }
                    if(op==4){//除法
                        i--;
                        continue;
                    }
                }
                if(no>=2) {
                    int left_kuo = (int) (Math.random() * no  + 1);
                    int right_kuo = (int) (Math.random() * (no+1 - left_kuo) + 1 + left_kuo);
                    qustr.insert(2*(left_kuo-1), '(');
                    qustr.insert(2*right_kuo, ')');
                }
                qustr.append('=');
                Question.add(qustr.toString());
                Calculator cal=new Calculator();
                Answer.add(""+cal.caculate(qustr.toString()));
            }







        for(int j=0;j<m;j++){//分数题目
               Scanner in = new Scanner(System.in);//真分数的计算
               int op=(int)(Math.random()*4+1);
               int[] f1 =createFraction();
               int[] f2 =createFraction();
               int j1=GCD(f1[0],f1[1]);
               f1[0]=f1[0]/j1;//化简分数
               f1[1]=f1[1]/j1;
               j1=GCD(f2[0],f2[1]);
               f2[0]=f2[0]/j1;
               f2[1]=f2[1]/j1;
               int gbs = LCM(f1[1],f2[1]);

             if(op==1){//加法
                  Question.add("("+f1[0]+"/"+f1[1]+")+("+f2[0]+"/"+f2[1]+")=");
                  int num1=f1[0]*f2[1]+f2[0]*f1[1];
                  int num2=f1[1]*f2[1];
                  int num3=GCD(num1,num2);
                  num1=num1/num3;
                  num2=num2/num3;
                  String a=new String();
                  if(num1==num2)
                    {
                        a="1";
                    }
                    else {
                      a = num1 + "/" + num2;
                  }
                  Answer.add(a+"");

              }
               if(op==2){//减法
                   int num1=f1[0]*f2[1]-f2[0]*f1[1];
                   if(num1>0){  //防止出现负数
                     Question.add("("+f1[0]+"/"+f1[1]+")-("+f2[0]+"/"+f2[1]+")=");
                     int num2=f1[1]*f2[1];
                     String a=new String();
                     if(num1==0)
                        {
                            a="0";
                        }
                        else
                        {
                        int num3=Math.abs(GCD(num1,num2));
                        num1=num1/num3;
                        num2=num2/num3;
                        if(num1==num2)
                        {
                            a="1";
                        }
                        else
                        {
                            a=num1+"/"+num2;
                        }
                        }
                     Answer.add(a+"");
               }else{
                   Question.add("("+f2[0]+"/"+f2[1]+")-("+f1[0]+"/"+f1[1]+")=");
                     int num11=f2[0]*f1[1]-f1[0]*f2[1];
                     int num2=f1[1]*f2[1];
                     String a=new String();
                     if(num11==0)
                        {
                            a="0";
                        }
                        else
                        {
                            int num3=Math.abs(GCD(num11,num2));
                            num11=num11/num3;
                            num2=num2/num3;
                            if(num11==num2)
                            {
                                a="1";
                            }
                            else
                            {
                                a=num11+"/"+num2;
                            }
                        }
                      Answer.add(a+"");



               }
                  }
              if(op==3){//乘法
                     Question.add("("+f1[0]+"/"+f1[1]+")*("+f2[0]+"/"+f2[1]+")=");
                     int num1= f1[0]*f2[0];
                     int num2 = f1[1]*f2[1];
                     int num3=GCD(num1,num2);
                     String a=new String();
                     num1= num1/num3;
                     num2 = num2/num3;
                  if(num1==num2)
                        {
                            a="1";
                        }
                        else
                        {
                            a=num1+"/"+num2;
                        }
                     Answer.add(a+"");
                  }
              if(op==4){//除法
                     Question.add("("+f1[0]+"/"+f1[1]+")÷("+f2[0]+"/"+f2[1]+")=");
                     int num1= f1[0]*f2[1];
                     int num2 = f1[1]*f2[0];
                     int num3=GCD(num1,num2);
                     String a=new String();
                     num1= num1/num3;
                     num2 = num2/num3;
                     if(num1==num2)
                        {
                            a="1";
                        }
                        else
                        {
                            a=num1+"/"+num2;
                        }
                     Answer.add(a+"");
              }
        }

        //输出题目
        JTextArea0.setText("");
        for(String string : Question){
            num ++;
            JTextArea0.append("("+num+")、"+string+"\n");
        }
    }

计算

    public class Calculator {


                private Stack<Long> numberStack = null;

                private Stack<Character> symbolStack = null;

                
                public long caculate(String numStr) {


                    // 初始化栈
                    numberStack = new Stack<Long>();
                    symbolStack = new Stack<Character>();
                    // 用于缓存数字,因为数字可能是多位的
                    StringBuffer temp = new StringBuffer();
                    // 从表达式的第一个字符开始处理
                    for (int i = 0; i < numStr.length(); i++) {
                        char ch = numStr.charAt(i); // 获取一个字符
                        if (isNumber(ch)) { // 若当前字符是数字
                            temp.append(ch); // 加入到数字缓存中
                        } else { // 非数字的情况
                            String tempStr = temp.toString(); // 将数字缓存转为字符串
                            if (!tempStr.isEmpty()) {
                                long num = Long.parseLong(tempStr); // 将数字字符串转为长整型数
                                numberStack.push(num); // 将数字压栈
                                temp = new StringBuffer(); // 重置数字缓存
                            }
                            // 判断运算符的优先级,若当前优先级低于栈顶的优先级,则先把计算前面计算出来
                            while (!comparePri(ch) && !symbolStack.empty()) {
                                long b = numberStack.pop(); // 出栈,取出数字,后进先出
                                long a = numberStack.pop();
                                // 取出运算符进行相应运算,并把结果压栈进行下一次运算
                                switch ((char) symbolStack.pop()) {
                                    case '+':
                                        numberStack.push(a + b);
                                        break;
                                    case '-':
                                        numberStack.push(a - b);
                                        break;
                                    case '*':
                                        numberStack.push(a * b);
                                        break;
                                    case '/':
                                        numberStack.push(a / b);
                                        break;
                                    default:
                                        break;
                                }
                            } // while循环结束
                            if (ch != '=') {
                                symbolStack.push(new Character(ch)); // 符号入栈
                                if (ch == ')') { // 去括号
                                    symbolStack.pop();
                                    symbolStack.pop();
                                }
                            }
                        }
                    } // for循环结束

                    return numberStack.pop(); // 返回计算结果
                }

            
                private String removeStrSpace(String str) {
                    return str != null ? str.replaceAll(" ", "") : "";
                }

                private boolean isStandard(String numStr) {
                    if (numStr == null || numStr.isEmpty()) // 表达式不能为空
                        return false;
                    Stack<Character> stack = new Stack<Character>(); // 用来保存括号,检查左右括号是否匹配
                    boolean b = false; // 用来标记'='符号是否存在多个
                    for (int i = 0; i < numStr.length(); i++) {
                        char n = numStr.charAt(i);
                        // 判断字符是否合法
                        if (!(isNumber(n) || "(".equals(n + "") || ")".equals(n + "")
                                || "+".equals(n + "") || "-".equals(n + "")
                                || "*".equals(n + "") || "/".equals(n + "")
                                || "=".equals(n + ""))) {
                            return false;
                        }
                        // 将左括号压栈,用来给后面的右括号进行匹配
                        if ("(".equals(n + "")) {
                            stack.push(n);
                        }
                        if (")".equals(n + "")) { // 匹配括号
                            if (stack.isEmpty() || !"(".equals((char) stack.pop() + "")) // 括号是否匹配
                                return false;
                        }
                        // 检查是否有多个'='号
                        if ("=".equals(n + "")) {
                            if (b)
                                return false;
                            b = true;
                        }
                    }
                    // 可能会有缺少右括号的情况
                    if (!stack.isEmpty())
                        return false;
                    // 检查'='号是否不在末尾
                    if (!("=".equals(numStr.charAt(numStr.length() - 1) + "")))
                        return false;
                    return true;
                }

            
                private boolean isNumber(char num) {
                    if (num >= '0' && num <= '9')
                        return true;
                    return false;
                }

                
                private boolean comparePri(char symbol) {
                    if (symbolStack.empty()) { // 空栈返回ture
                        return true;
                    }


                    char top = (char) symbolStack.peek();
                    if (top == '(') {
                        return true;
                    }
                    // 比较优先级
                    switch (symbol) {
                        case '(': // 优先级最高
                            return true;
                        case '*': {
                            if (top == '+' || top == '-') // 优先级比+和-高
                                return true;
                            else
                                return false;
                        }
                        case '/': {
                            if (top == '+' || top == '-') // 优先级比+和-高
                                return true;
                            else
                                return false;
                        }
                        case '+':
                            return false;
                        case '-':
                            return false;
                        case ')': // 优先级最低
                            return false;
                        case '=': // 结束符
                            return false;
                        default:
                            break;
                    }
                    return true;
                }


            }
        

运行结果:

1109682-20180325200702348-413295576.png

效能分析:

1109682-20180325200709441-248377915.png

三、小结感受

1109682-20180325200806565-698206896.jpg

结队编程在大二学习JAVA时有尝试过,只是初步体验了一下,这次与大佬结队希望真的能够学到东西提升自己,有个领航员,可以时刻发现问题。两人一起寻找问题发现问题感觉效率比较高,但编程过程还是比较坎坷,希望最后能够一加一大于二,乃至远大于二。

PSP2.1个人开发流程预估耗费时间(分钟)实际耗费时间(分钟)
Planning计划158
Estimate明确需求和其他相关因素,估计每个阶段的时间成本104
Development开发120140
Analysis需求分析需求分析 (包括学习新技术)1010
Design Spec生成设计文档00
Design Review设计复审108
Coding Standard代码规范22
Design具体设计1015
Coding具体编码4060
Code Review代码复审2010
Test测试(自我测试,修改代码,提交修改)1515
Reporting报告1512
·测试报告22
·计算工作量1510
·并提出过程改进计划105

转载于:https://www.cnblogs.com/ghnb/p/8646789.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值