软件工程第三次作业--求最大子段和

一、最大连续子数组和(最大子段和)

问题背景

给定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。

问题分析

当给定一组数组时,从i=0开始,令j=i,j每加1,就得到一个当前子段和,若大于sum,将其赋值为sum,累计相加,直到数组的最后一个数字,可得在i=0时的最大子段;进行循环,最后通过不断地比较而得最大子段和。以下将以流程图的形式给出该题的具体思路,同时也更便于单元测试。

程序代码:https://coding.net/u/llwang/p/AddMax/git/tree/master

二、单元测试中不同覆盖方法的比较

1.语句覆盖:语句覆盖是最起码的结构覆盖要求,语句覆盖要求设计的测试用例,使得程序中每条语句至少被执行一次。
2.判定覆盖:判定覆盖又称为分支覆盖,它要求程序中每个判定至少有一次为真值,有一次为假值。
3.条件覆盖:要求设计足够多的测试用例,使得判定中的每个条件获得各种可能的结果,即每个条件至少有一次为真值,有一次为假值。
4.条件/判定覆盖:要求使得判定中每个条件的所有可能结果至少出现一次,每个判定本身所有可能结果也至少出现一次。
5.组合覆盖:要求设计足够多的测试用例,使得每个判定中条件结果的所有可能组合至少出现一次。

三、单元测试

1.程序清单

#include<iostream>
using namespace std;

int MaxAdd(int n, int arr[]){
	int sum = 0;
	for (int i = 0; i < n; i++){
		int thisSum = 0;
		for (int j = i; j < n; j++){
			thisSum += arr[j];
			if (thisSum > sum)
				sum = thisSum;
		}
	}
	if (sum < 0) sum = 0;
	return sum;
}

int main(){
	int n, sum = 0;
	int arr[100];
	cin >> n;
	for (int i = 0; i < n; i++){
		cin >> arr[i];
	}
	sum = MaxAdd(n, arr);
	cout << sum << endl;
	system("pause");
	return 0;
}

2.流程图

3.测试代码

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

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
int MaxAdd(int n, int arr[]){
	int sum = 0;
	for (int i = 0; i < n; i++){
		int thisSum = 0;
		for (int j = i; j < n; j++){
			thisSum += arr[j];
			if (thisSum > sum)
				sum = thisSum;
		}
	}
	if (sum < 0) sum = 0;
	return sum;
}
namespace UnitTest1
{		
	TEST_CLASS(UnitTest1)
	{
	public:
		
		TEST_METHOD(TestMethod1)
		{
			// TODO:  在此输入测试代码
			int arr[5] = { -1, 2, -1, 0, -2};
			int sum = MaxAdd(5, arr);
			Assert::AreEqual(2, sum);
		}
		TEST_METHOD(TestMethod2)
		{
			// TODO:  在此输入测试代码
			int arr[5] = { -1, 2, 4, 3, 2 };
			int sum = MaxAdd(5, arr);
			Assert::AreEqual(11, sum);
		}
		TEST_METHOD(TestMethod3)
		{
			// TODO:  在此输入测试代码
			int arr[5] = { -2, 1, 0, 1, -1 };
			int sum = MaxAdd(5, arr);
			Assert::AreEqual(2, sum);
		}
		TEST_METHOD(TestMethod4)
		{
			// TODO:  在此输入测试代码
			int arr[5] = { -2, 1, 1, 2, 3 };
			int sum = MaxAdd(5, arr);
			Assert::AreEqual(7, sum);
		}

	};
}

4.样例分析

我选择的是组合覆盖,即每个条件的所有可能列出,并进行组合,经过分析,我选择了四组用例,覆盖了所有的组合情况。程序包含两个判断条件,有四种组合,如(1)thisSum>=sum,thisSum<=sum;
(2)sum>=0,sum<=0

因可由四种组合写出四组测试样例:
thisSum>=sum&&sum>0;thisSum>=sum&&sum<=0;
thisSum<=sum&&sum>0;thisSum<sum&&sum<=0.



5.总结

上次作业我学会了Junit单元测试,这次作业因为想用C++编程,于是又学会了visual studio自带的单元测试,因此我觉得平时多给自己一些学习的机会,俗话说技多不压身。同时,自己设计样例进行单元测试,这使我们对程序可能出现的各种情况都很清楚。单元测试在编程中起着至关重要的作用,但是我们的练习还远远不够,为了给以后更好的工作做铺垫,一定要多多练习单元测试,全面的,更好的设计测试案例,以提高工作效率。

posted @ 2018-03-30 20:18  yongliwang  阅读(212)  评论(0编辑  收藏  举报