“练习的时候,不要害怕出错,错误越多,你得到的经验就会越多,理解的就越深刻。”  by Y


题目要求:数组成环,输入一个数组,输出最大连续子数组和以及其的区间下标。

 

一、项目实践总结

  算法设计:

    最大连续数组和算是一个小的dp问题,只需要理解状态转移方程---dp[ i ]  = max( dp[ i -1 ] ) + arr[ i ] ,arr[ i ] )  (dp[i]为以i为结尾的最大连续区间和)  此放大的时间复杂度为O(n) 。在本次作业中,不考虑时间复杂度的问题,所以不需要用dp法。题目要求数组成环,故而可以用下标(i + 1) % n 来形成循环,存储下标的时候注意每次更新最大值时修改右端点即可。

  编码:

    这次作业采用java语言编程,面向过程的思想有点严重,加上对于java语言掌握能力不是很高,所以敲起来耗时有点长。基于面向对象,我便将运算求取最大连续子数组和部分写了一个类,让这个类可以有方法求解,然后再main.java里面直接调用即可。

  贴一下代码:

package com.company;
import java.util.ArrayList;
public class MaxArr {
    static class MaxSumPosition{
        int sum;
        int l;
        int r;
    }
    public static MaxSumPosition getResult(ArrayList<Integer> array,MaxSumPosition maxSumPosition) {
        int ans = 0;
        maxSumPosition.sum = array.get(0);
        for(int i=0; i< array.size(); i++) {
            if(ans <= 0) {
                ans = array.get(i);
                maxSumPosition.l = maxSumPosition.r = i;
            }else {
                ans += array.get(i);
            }
            if(ans > maxSumPosition.sum) {
                maxSumPosition.sum = ans;
                maxSumPosition.r = i;
            }
        }
        return maxSumPosition;
    }
    public MaxSumPosition Getmax(int array[],int n) {
        MaxSumPosition maxSumPosition = new MaxSumPosition();
        int maxx = Integer.MIN_VALUE;
        maxSumPosition.l = 0;
        maxSumPosition.r = 0;
        for(int i = 0; i < n; i ++) {
            ArrayList<Integer> list = new ArrayList<>();
            for(int j = i; ( j + 1 ) % n != i; j = (j + 1) % n) {
                list.add(array[j]);
            }
            MaxSumPosition maxSumPosition1 = new MaxSumPosition();
            maxSumPosition1 = getResult(list,maxSumPosition1);
            if(maxSumPosition.sum < maxSumPosition1.sum) {
                maxSumPosition.sum = maxSumPosition1.sum;
                maxSumPosition.l = ( maxSumPosition1.l + i ) % n;
                maxSumPosition.r = ( maxSumPosition1.r + i ) % n;
            }
        }
        return maxSumPosition;
    }
}

 

  单元测试:

    本程序中,我对我的Getmax方法进行测试,利用junit创建测试类。在书写测试类时少了@org.junit.Test,在回头检查时发现。由于自己对单元测试掌握不熟练,在创建的时候,多次回顾课内知识,出了很多次错,现在已经基本掌握了单元测试。

贴一下代码:

package com.company;
import org.junit.Assert;
import static org.junit.Assert.*;
public class MaxArr_GetmaxTest {
    @org.junit.Test
    public void Getmax(){
        int n = 5;
        int l=0,r=0;
        int[] array = {2,1,12,-25,54};
        MaxArr maxarr = new MaxArr();
       MaxArr.MaxSumPosition maxSumPosition = maxarr.Getmax(array,n);
        Assert.assertEquals(69,maxSumPosition.sum);
        Assert.assertEquals(4,maxSumPosition.l);
        Assert.assertEquals(2,maxSumPosition.r);
    }
}

 

  所用时间:

    时间估计相差不多。程序设计,代码实现用时较短,单元测试部分耗时较长,主要还是自己当时初次了解单元测试,运用的不熟练。总体完成本次项目耗时差不多半天多,很不错了。

 

二、问题及解决方法

问题1:单元测试时语句覆盖率最开始没有达到100%,Main.java没用到,但是被包含到测试运行中了。

  解决方法:将Main.java移除项目。

  问题2:单元测试最初创建没跑成功。

  解决方法:本次项目我是重新开了一个项目文件,但是没有先导入junit测试就直接进行测试,所以我重新看了一遍测试步骤,主要还是当时没理解。

 

三、认知变化

  1.测试技能认知加深。

    以往的程序设计,出测试样例用眼看,找特殊值、特殊情况,本次作业的测试用例不仅要答案正确,还需要满足单元测试的语句覆盖率达到100%。不仅如此,为了方便测试,也就是符合面向对象的语言书写,我将计算最大连续子数组和部分的代码放到了一个类里面,主函数直接调用类的方法,不然也不好写测试类。

 

四、心得体会

最大连续数组和算法思想起来不算困难,但对于java掌握一般,语句实现还是踩了点坑,加上对测试的掌握不是很熟练,整体来说耗时有点长。之前都是程序设计,仅仅是算法设计部分。即便是对程序进行测试,也是debug一下,出数据测试也是找特殊值判断这个程序对不对,不会想到语句覆盖、判定覆盖、条件覆盖、判定组合覆盖等等。这次作业,让我对软件测试的理解加深,掌握了如何用junit进行单元测试,如何设计符合要求的测试用例。