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

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

问题背景

给定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.流程图

1346218-20180330195525891-461580477.jpg

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.

1346218-20180330202112152-318362649.png
1346218-20180330202123807-505116318.png
1346218-20180330202137749-1750612775.png

5.总结

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

转载于:https://www.cnblogs.com/ylwang/p/8672891.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值