软件工程第三次作业
题目要求
题目(1):最大连续子数组和(最大子段和)
背景
问题: 给定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变量才存放目前为止最大的和,再用一个循环就能解决。
然后是整组数据的分别求最大连续子数和,于是我在一个循环里从第一个数据重复上一个算法,并用一个新的变量subarraysum来记录最大的字数和。在每一次循环的时候我把sum置零,这样即使所有都是负数的情况下最后subarraysum的值为0,符合题意。
程序代码如下
[码!](https://dev.tencent.com/u/dtid_08055112ef5e3100/p/937171599/git/tree/master)
#include <stdio.h>
int Subarraysum(int a[], int n)
{
int i = 0, j, sum, subarraysum = 0;
for (i; i < n - 1; i++)
{
sum = 0;
for (j = i ; j < n - 1; j++)
{
sum += a[j];
if (sum > subarraysum)
{
subarraysum = sum;
}
}
}
return subarraysum;
}
int main()
{
int i = 0, n ,j ,sum;
int a[100];
int subarraysum = 0;
scanf_s("%d", &n);
for (i = 0; i < n; i++)
{
scanf_s("%d", &a[n]);
}
subarraysum = Subarraysum(a, n);
printf_s("%d", subarraysum);
return 0;
}
单元测试
我采用如下三组数据
1 ,9 ,-5 ,16 ,2 ,4 ,-7
-7 ,-9 ,-3 ,-2
-1,9 ,-5 ,16 ,2 ,4 ,-7
测试结果
运行通过说明代码没有问题
测试代码如下
#include "stdafx.h"
#include "CppUnitTest.h"
#include"C:\Users\paranoia\source\repos\homework3\homework3\源.cpp"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod1)
{
int a[7] = { 1 ,9 ,-5 ,16 ,2 ,4 ,-7 }, n = 7 , sum;
sum = Subarraysum(a, n);
Assert::AreEqual(sum , 27);
}
TEST_METHOD(TestMethod2)
{
int a[4] = { -7 ,-9 ,-3 ,-2 }, n = 4, sum;
sum = Subarraysum(a, n);
Assert::AreEqual(sum, 0);
}
TEST_METHOD(TestMethod3)
{
int a[7] = { -1,9 ,-5 ,16 ,2 ,4 ,-7 }, n = 7, sum;
sum = Subarraysum(a, n);
Assert::AreEqual(sum, 26);
}
};
}