求最大字段和

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。
-- 引用自《百度百科

具体要求

  (1) 要求写出可运行的完整代码提交至GitHub或者Coding.net系统中,并将代码地址附到博客内,可以参考这篇博文
  (2) 请从语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖五个覆盖标准中(条件组合覆盖难度较大,鼓励尝试,但请谨慎选择),任选一个标准设计测试用例
  (3) 请利用自动测试工具对程序进行测试
  (4) 请将程序运行结果和自动测试分析结果截图附到博客中

2.解决办法

  当程序开始时我们进行初始化,令max=0,然后用n记录我们所输入的输的个数,若令a[i]记录我们所输入的数所组成的数组,且令b[0]=a[0]。b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,并且1<=j<=n。则所求的最大子段和为max b[j],1<=j<=n。由b[j]的定义可易知,当b[j-1]>0时b[j]=b[j-1]+a[j],否则b[j]=a[j]。故b[j]的动态规划递归式为:b[j]=max(b[j-1]+a[j],a[j]),1<=j<=n。

流程图如下:

主流程图:

![](https://images2018.cnblogs.com/blog/1345898/201804/1345898-20180401134302485-92634016.png)
核心算法流程如下:
![](https://images2018.cnblogs.com/blog/1345898/201804/1345898-20180401134414737-1184550237.png)
##3.程序及其测试 用c++编写的程序如下: ###头文件:
#include <stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
int qiumax(int n, int a[]);

主程序

源代码

#include"标头.h"
int main()
{
	int qiumax(int n, int a[]);
	int n;//输入数组的个数
	int a[1000];//记录所输入的数组
	int i,max;
	cin >> n;
	for (i = 0; i<n; i++)
	{
		cin >> a[i];
	}
	max = qiumax(n, a);
	printf("%d\n", max);
	system("pause");
	return 0;
}
int qiumax(int n, int a[])
{
	int b[1000];
	int i;
	int max = 0;
	b[0] = a[0];
	//核心算法求最大子树和并记录在max中
	for (i = 1; i<n; i++)
	{
		if (b[i - 1]>0)
			b[i] = b[i - 1] + a[i];
		else
			b[i] = a[i];
		if (b[i]>max)
			max = b[i];
	}
	return max;
}

  手动测试,在这里我先进行了一下运行,输入5个数,分别是,1,-5,6,2,-3。经过计算可得我们应该得到的值为8。

进行单元测试的程序

  在五种测试中我选择了条件组合覆盖。在核心测试程序中我们总共有两个条件判定,我们根据子程序的流程图将其的几种情况都考虑到得到了三个测试数据
(1)总数为6个,数据为:-1, -2, -3, -4, -5, -9,根据算法我们可以得到其最大字数和为0;
(2)总数为6个,数据为:-3, 8, -5, -1, 7, -9,根据算法我们可以得到其最大字数和为9;
(3)总数为9个,数据为:5, -1, 4, -9, 2, 10, -3, 5,根据算法我们可以得到其最大字数和为14;

#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
#include <stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
int qiumax(int n, int a[])
{
	int b[1000];
	int i;
	int max = 0;
	b[0] = a[0];
	//核心算法求最大子树和并记录在max中
	for (i = 1; i<n; i++)
	{
		if (b[i - 1]>0)
			b[i] = b[i - 1] + a[i];
		else
			b[i] = a[i];
		if (b[i]>max)
			max = b[i];
	}
	return max;
}
namespace UnitTest1
	// TODO:  在 STDAFX.H 中引用任何所需的附加头文件,
	//而不是在此文件中引用
{		
	TEST_CLASS(UnitTest1)
	{
	public:
		
		TEST_METHOD(TestMethod1)
		{
			// TODO:  在此输入测试代码
			int a[6] = { -1, -2, -3, -4, -5, -9 };
			int sum = qiumax(6, a);
			Assert::AreEqual(0, sum);
		}
		TEST_METHOD(TestMethod2)
		{
			// TODO:  在此输入测试代码
			int a[6] = { -3, 8, -5, -1, 7, -9 };
			int sum = qiumax(6, a);
			Assert::AreEqual(9, sum);
		}
		TEST_METHOD(TestMethod3)
		{
			// TODO:  在此输入测试代码
			int a[9] = { 5, -1, 4, -9, 2, 10, -3, 5};
			int sum = qiumax(9, a);
			Assert::AreEqual(14, sum);
		}

	};
}

首先在源程序上创建一个单元测试,如下图所示:

测试结果如下:

4.总结

  在这一次的实际操作中,我们又一次加深了对Markdown编辑器的应用和单元测试的要点,为我们以后打下了坚实的基础,除此之外我们还学会了几种单元测试的覆盖情况,我们通过不断地交流和查询,使我们的合作能力得到了进一步的加强,我们成长了很多,希望我们都可以更进一步。

posted @ 2018-04-01 15:11  1825361163  阅读(1348)  评论(0编辑  收藏  举报