软件工程(2018)第三次作业

最大连续子数组和

一.问题描述

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。
引用自《百度百科》

二.问题分析

已知一个sum数组,sum[i]表示第1个数到第i个数的和,于是sum[j] - sum[i-1]表示第i个数到第j个数的和。那么,以m为起点,n为终点最大子序列和为sum[n] - sum[m-1]。并且,sum[m]必然是sum[1],sum[2]...sum[n-1]中的最小值!如果在维护计算sum数组的时候,同时维护之前的最小值,答案就会迎刃而解。
程序代码:https://github.com/ZhangydA/CodeCollection

public class ContinuousMaximum {
	public int continuousMaxinum(int arr[]){
		int counter = 0;
		for (int i = 0;i < arr.length;i ++){
			if (arr[i] < 0) counter ++;
		}
		//如果所有的值都为负值,返回0
		if (counter == arr.length) return 0;
		int sum = 0,ans = Integer.MIN_VALUE,mins = 0;
		for (int i = 0;i < arr.length;i ++){
			sum += arr[i];
			if (sum - mins > ans)
				ans = sum - mins;
			if (mins > sum)
				mins = sum;
		}
		return ans;
	}
}

测试类方法

import java.util.Scanner;

public class Test {
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int[] arr = new int[n];
		for (int i = 0;i < n;i ++){
			arr[i] = input.nextInt();
		}
		System.out.println(new ContinuousMaximum().continuousMaxinum(arr));
		input.close();
	}
}

三.逻辑覆盖方法的比较

  1.语句覆盖:语句覆盖是最起码的结构覆盖要求,语句覆盖要求设计足够多的测试用例,使得程序中每条语句至少被执行一次。
  2.判定覆盖:判定覆盖又称为分支覆盖,它要求设计足够多的测试用例,使得程序中每个判定至少有一次为真值,有一次为假值。
  3.条件覆盖:条件覆盖要求设计足够多的测试用例,使得判定中的每个条件获得各种可能的结果,即每个条件至少有一次为真值,有一次为假值。
  4.条件/判定覆盖:设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身所有可能结果也至少出现一次。
  5.组合覆盖:要求设计足够多的测试用例,使得每个判定中条件结果的所有可能组合至少出现一次。 覆盖方法的优缺点及比较

四.组合覆盖

1.程序流程图

图片名称 ###2.选择分析测试样例及运行结果 通过流程图我们可知,组合覆盖一共有5中情况,分别是 B、ACE、ACF、ADE、ADF,经过了多次分析,选择了{-1,-2,-3,-4,-5}和{-2,5,-6,3,4}两组数据进行分析组合覆盖。 **第一组测试样例:** 样例运行结果 图片名称 **第二组测试样例:** (1).样例运行结果 图片名称 (2).数据路径覆盖分析
数值 sum mins ans sum - mins > ans mins > sum 覆盖路径
-2 -2 -oo 0 Y Y ACE
5 3 -2 -2 Y N ACF
-6 -3 5 -2 N Y ADE
3 0 5 -3 N N ADF
4 4 5 - 3 Y N ACF
由上表可知,该组样例包含了ACE、ACF、ADE、ADF这四种情况,结合上述两组样例,覆盖了所有的情况,并且运行的结果与预期的结果一致。

3.JUnit自动测试

为了进一步的确任程序的正确性,接下来通过JUnit对多组数据进行自动测试,JUnit之参数化测试和成组测试的使用查看 这篇文章
(1).JUnit自动测试类

package cn.sau.MaxSum;

import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class ContinuousMaximumAutoTest {
	
	private int excepted;
	private int[] array;
	public ContinuousMaximumAutoTest(int excepted,int[] array){
		this.excepted = excepted;
		this.array = array;
	}
	/** 
     * 3.由@Parameterized.Parameters修饰一个 
     * public static Collection xxx() 
     */ 
    @Parameterized.Parameters  
    public static Collection data() { 
        return Arrays.asList(new Object[][] {  
            { 20, new int[]{-2,11,-4,13,-5,-2}},  
            { 7, new int[]{-2,5,-6,3,4}},//  
            { 0,  new int[]{-1,-2,-3,-4,-5}},  
            { 12,  new int[]{-1,6,-7,3,4,5,-6}}  
        });  
    }  
	@Test
	public void test() {
		assertEquals(excepted,new ContinuousMaximum().continuousMaxinum(array));
	}
}

(2).测试类运行结果

五.总结

经过本次的作业,让我受益最大的有两点,第一点是学会了自己选择测试样例对自己的程序进行测试,第二点是学会了多组样例同时针对一个函数进行检测

posted @ 2018-03-27 22:47  ZhangyiA  阅读(286)  评论(0编辑  收藏  举报