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

一、作业题目描述

最大连续子数组和: 给定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。

二、 题目分析

该题目给的要求是求数组的最大子数列和。
对于最大子数列和的问题,在时间复杂度为O(n)的情况下,求解时考虑两个基本事实:
事实1:
对于一个从头开始的子数列,如果这个数列的和小于0,那么这个子数列不可能在所要求的最大子数列里。
事实2:
对于一个首尾随机的有序数列,数列和为正向扫描的当前最大的子数列,如果加上下一个数后,数列的和小于0了,那么原数列加上后一个数从而组成的数列就不会是最大连续子数列。此时应该保持原数列的和的值,再向后寻找的时候需要将下一个数作为查找的子数列的首项。
依照此想法,可获得下面的求解方法:
将数列从头到尾依次扫描,逐次相加。每次相加的时候查看加和是否比已知的最大连续子数列和大。如果较大,则替换最大和,否则,查看加和是否为负数。如果为负数,则保留之前的最大和,同时将先前的数列清空,从下一个数开始重新相加,比较最大值。

三、流程图和实现代码

3.1 流程图

流程图如下:

3.2 具体代码

根据流程图可编写出具体代码。
对该算法的代码如下:

	public int  GetMax() {
		int MaxNow = 0;
		int NumNow = 0;
		if(n < 0) {
			return -1;
		}
		for(int i = 0 ;i < n ;i++) {
			NumNow += NumList[i];
			if(NumNow > MaxNow) {
				MaxNow = NumNow;
			}
			else if( NumNow < 0) {
				NumNow = 0;
			}
		}
		return MaxNow;
	}

可执行的代码地址:github代码

四、单元测试

4.1测试覆盖方式选择以及判断分析

选择条件组合覆盖方式。
由流程图可知,该流程主要的判断有四个:
1.对n的判断:
n<0; n>=0;

2.对i的判断:
i<n; i>=n;

3.对NumNow是否大于MaxNow的判断:
NumNow>MaxNow; NumNow<MaxNow;

4.对NumNow是否小于0的判断:
NumNow>0; NumNow<0;

由于2中对i的判断是在循环中进行的,而且是在n>0的情况下必然发生的事情,所以可以归类为对n的判断。
在3和4中的对NumNow的判断,可以整合为对NumNow>MaxNow、0<=NumNow<=MaxNow、NumNow<0三种情况判断。而且因为该判断处在循环中,所以有一起发生的可能。

4.2 条件组合覆盖方式的可能组合

所有可能的组合为:
1.n<0;
2.n=0;
3.n>0;NumNow>MaxNow;
4.n>0;NumNow>MaxNow;0<=NumNow<=MaxNow;
5.n>0;NumNow<0;
6.n>0;NumNow>MaxNow;0<=NumNow<=MaxNow;NumNow<0;
7.n>0;0<=NumNow<=MaxNow;
8.n>0;0<=NumNow<=MaxNow;NumNow<0;
9.n>0;NumNow>MaxNow;NumNow<0;

4.3依据测试组合设计样例

所以设计测试样例为:

  1. n=6,数列为:-1,-2,-3,-4,-5,-6;
    满足组合:5;
  2. n=6,数列为:-2,11,-4,13,-5,-2;
    满足组合:6;
  3. n=0,数列为:空;
    满足组合:2;
  4. n=-1,数列为:空;
    满足组合:1;
  5. n=6,数列为:1,2,4,5,6,7;
    满足组合:3;
  6. n=6,数列为:11,11,-4,-1,-1,-1;
    满足组合:4;
  7. n=6,数列为:0,0,0,0,0,0;
    满足组合:7;
  8. n=6,数列为:0,-1,-4,-5,-5,-2;
    满足组合:8;
  9. n=6,数列为:-1,3,-4,-5,-5,-2;
    满足组合:9;

4.4测试代码

测试代码如下:

package homework;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class NumListTest {

	@Test
	void testGetMax1() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {-1,-2,-3,-4,-5,-6}; 
		assertEquals(0,a.GetMax());
	}
	@Test
	void testGetMax2() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {-2,11,-4,13,-5,-2}; 
		assertEquals(20,a.GetMax());
	}
	@Test
	void testGetMax3() {
		NumList a = new NumList();
		a.n =  0;
		a.NumList =new int[] {}; 
		assertEquals(0,a.GetMax());
	}
	@Test
	void testGetMax4() {
		NumList a = new NumList();
		a.n =  -1;
		a.NumList =new int[] {}; 
		assertEquals(-1,a.GetMax());
	}
	@Test
	void testGetMax5() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {1,3,4,5,6,7}; 
		assertEquals(26,a.GetMax());
	}
	@Test
	void testGetMax6() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {11,11,-4,-1,-1,-1}; 
		assertEquals(22,a.GetMax());
	}
	@Test
	void testGetMax7() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {0,0,0,0,0,0}; 
		assertEquals(0,a.GetMax());
	}
	@Test
	void testGetMax8() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {0,-1,-4,-5,-5,-2}; 
		assertEquals(0,a.GetMax());
	}
	@Test
	void testGetMax9() {
		NumList a = new NumList();
		a.n =  6;
		a.NumList =new int[] {-1,3,-4,-5,-5,-2}; 
		assertEquals(3,a.GetMax());
	}

}

测试代码地址github代码_测试

4.5测试结果:

测试截图如下:

posted @ 2019-04-20 17:54  陈涌智  阅读(257)  评论(0编辑  收藏  举报