最大连续子数组和
题目要求
问题: 给定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。
-- 引用自《百度百科》
设计思路
使用穷举法进行设计,分别求出所有连续子数组的和,将初始和的最大值设为0,然后与现在的和的最大值进行比较,若和的数值大于目前和的最大值,则替换目前和的最大值,以此找出最大的和,输出。
实现
本次使用Eclipse进行设计,有了上次作业的经验,本次程序的实现并没有遇到太多问题。
以下为对个子数组分别求和的函数,完整程序见末尾coding链接。
public static int calculate(int n,int a[]) {
int i,j,MAX=0,S=0;
for(i=0;i<n;i++)
{
for(j=0;j<n-i;j++)
{
S=S+a[i+j];
if(MAX<S) MAX=S;
}
S=0;
}
return MAX;
下图为编写完成整个程序
2. 测试及其覆盖
编写
本次测试使用了常规的程序运行测试,和用junit编写程序覆盖的自动样例进行测。
以下为编写的junit自动测试部分
该测试部分分别测试了(设初始maxsun=0)数组内全为负数时、全为正数时、正负交替时的情况,由于本次设计的思路比较简单所以这样就实现了覆盖测试。
package sum;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class SumMAXTest {
@Test
public void MAX1() {
int a1[]=new int[]{-1,-2,-3,-4,-5};
int b1=new sum.SumMAX().calculate(5, a1);
assertEquals(0,b1);
}
@Test
public void MAX2() {
int a1[]=new int[]{1,2,3,4,5};
int b1=new sum.SumMAX().calculate(5, a1);
assertEquals(15,b1);
}
@Test
public void MAX3() {
int a1[]=new int[]{-2,11,-4,13,-5,-2};
int b1=new sum.SumMAX().calculate(5, a1);
assertEquals(20,b1);
}
}
下图为编写的自动测试程序。
测试及其结果
下图为手动常规运行测试的样例
以下为运行Junit测试的结果
上图表明测试结果符合预期,结果正确,程序设计成功。
总结
本次作业的难度与复杂度较上次有所增加,对个人技术也有了更高的的要求。通过本次作业我们更好的了解了自己的个人开发能力,明确了需要增强学习与练习的方面,也通过本次作业更加熟悉了eclipse使用过程和junit自动测试的编写,也巩固的覆盖测试的知识,而且通过本次作业对这方面只是进行了实践。
本次完成作业过程中还是遇到许多问题,比如上次作业的使用eclipse编写的问题、使用junit测试的问题。这些问题体现了我个人对于开发环境的不熟练和练习过少等问题。希望通过努力下次完成作业时有所进步。
codeing链接:https://coding.net/u/JiangMiao/p/SumMax/git/blob/master/.gitignore?public=true