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


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

    问题背景

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

  • 相关阅读:
    记一次java程序内存溢出问题
    js 对象数据观察者实现
    requirejs和seajs使用感受
    maven根据不同的运行环境,打包不同的配置文件
    Quartz .net 一直运行失败
    Sql2008R2 日志无法收缩解决方案
    win7 64位英文版 ado驱动
    KB4284826 远程桌面发生身份验证错误,要求的函数不受支持
    Delphi System.zip patch with ZIP64 and LZMA supports
    native excel 文件已经打开的判断
  • 原文地址:https://www.cnblogs.com/ylwang/p/8672891.html
Copyright © 2020-2023  润新知