最大连续子数组和问题

题目要求:

题目(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。

-- 引用自《百度百科》

问题分析:

根据问题要求,我们需要输入n个整数。因此,首先设置一个变量n,用于保存将要输入的整数个数,并创建一个一维数组a[n](在此处我们需要使用指针来动态分配数组空间),用于保存输入的整数。根据问题要求,“当所给的整数均为负数时定义子段和为0”,因此在完成输入后,我们立即检查输入的整数是否全为负数。如果是,则输出‘0’。

虽然可以通过计算所有可能的组合来找出最大子段和,但这种方法的执行开销过大。因此,我们需要改进算法,只使用一次循环。由于最大子段和一定是正数,我们可以排除许多组合。因此,我们从第一个整数开始累加,当出现负数时,我们就舍弃之前的子段,并从当前位置继续向后累加子段。我们依次累加到最后一个整数,同时记录到目前为止出现的最大子段和。

我们设置两个变量:sub和max1,用于保存子段和和最大子段和的值。我们将它们的初始值都设为0。然后,从第一个整数开始逐个向后累加,每完成一次累加,立即比较当前sub的值与刚刚累加的整数a[i]的大小。如果sub小于a[i],则将a[i]的值赋给sub,以找出最大子段和。然后,我们比较max1和sub的大小,如果max1小于sub,则将sub的值赋给max1;否则,max1保持不变。当循环累加结束后,max1的值即为该连续子数组的最大子段和,我们输出max1的值。

源代码:

int find_max_add(int n,int a[])
{
int sum=0,max=0;
for(int i=0;i<n;i++)
{
sum+=a[i];
if(max<sum)
max=sum;
if(sum<0)
sum=0:
}
return max;
}

使用的是条件组合覆盖的方法,情况共分为以下四种:

(1)全部为0的情况

(2)全部为自然数

(3)全是0和负数

(4)综合情况

测试代码:

#include "pch.h"
#include "CppUnitTest.h"
#include "../Project/code.cpp"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{
	TEST_CLASS(UnitTest1)
	{
	public:

		TEST_METHOD(TestMethod1)
		{
			int test[6] = { 0,0,0,0,0,0 };
			Assert::AreEqual(0, find_max_add(6, test));
		}

		TEST_METHOD(TestMethod2)
		{
			int test[6] = { 0,1,2,3,4,5 };
			Assert::AreEqual(15, find_max_add(6, test));
		}

		TEST_METHOD(TestMethod3)
		{
			int test[6] = { 0,-1,-2,-3,-4,-5 };
			Assert::AreEqual(0, find_max_add(6, test));
		}

		TEST_METHOD(TestMethod4)
		{
			int test[6] = { -2,11,-4,13,-5,-2 };
			Assert::AreEqual(20, find_max_add(6, test));
		}
	};
}

 

测试结果:

代码所在Github地址:

https://github.com/Xuyafei143096/Software-engineering-assignments/tree/master/213428010102-%E5%BE%90%E4%BA%9A%E9%A3%9E-%E4%BD%9C%E4%B8%9A2%E4%BB%A3%E7%A0%81

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值