1. 程式人生 > >最大連續子數組和(最大子段和)及其條件覆蓋

最大連續子數組和(最大子段和)及其條件覆蓋

iostream new 指針 tps 自動測試 數組 組合 完成 sin

最大連續子數組和(最大子段和)問題

  • 背景
    ??問題: 給定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) 請將程序運行結果和自動測試分析結果截圖附到博客中
  • 問題分析
    ?? 根據題目分析,需要輸入n個整數,所以設置一個自變量n,保存要輸入的整數個數,以及一維數組a[n](此處需要用指針申請動態數組),用來保存輸入的整數,由於題目要求“當所給的整數均為負數時定義子段和為0”,所以輸入完成後立即判斷所輸入整數是否全為負數,如果全為負數,輸出‘0’;
    ??雖然算出所有組合便找出最大子段合,但是這樣程序執行開銷過大,所以改進算法,只使用一次循環。
    ?? 因為最大子段和一定是正數,這樣就排除了許多組合,所以從第一個整數開始累加,出現負數便舍棄之前的子段,從當前位置繼續向後累加子段,依次累加到最後一個整數,而此過程中還需要另外一個變量記錄到目前為止所出現的最大子段合。
    ?? 設置變量sub,max1保存子段和,初值為0,從第一個整數開始逐個向後累加,累加值保存在變量sub中,每完成一次累加,立即比較當前sub的值與剛剛所累加整數a[i]的大小,如果sub<a[i],則將a[i]的值賦給sub,為了找出最大子段合。需要用max1記錄最大的sub值,所以每累加一次之後都要比較max1與sub的大小,如果max1<sub,則將sub的值賦給max1,否則max1保持不變,當循環累加結束後,max1的值即為該連續子數組最大子段和,輸出max1的值。
  • 流程圖與源代碼
  1. 流程圖
    技術分享圖片

  2. 源代碼
    點此查看Github源代碼
#include <stdio.h>
#include<iostream>
#include<cstdlib>
using namespace std;

int MAX(int n,int *a)
{
    int  m, max1=0,sub=0;
    for (m = 0; m < n; m++)
    {
        sub += a[m];
        if(sub<a[m])
        {
            sub = a[m];
        }
        if (max1 < sub)
        {
            max1 = sub;
        }
    }
    return max1;
}

int main()
{
    int i=0,max=0,n=0,button=0;
    int* a = new int[n+1];
    cin >> n;
    if (n <= 0)
    {
    cout << max;
    system("pause");
    return 0;
    }
    return 0;
    for (i = 0; i < n; i++)
    {
        cin >> a[i];
        if (a[i] > 0)
        {
            button = 1;
        }
    }
    if (button == 0)
    {
        max = 0;
    }
    else
    {
        max = MAX(n,a);
    }
    cout << max << endl;
    system("pause");
    return 0;
}
  • 測試用例選擇
    判斷/條件覆蓋
\ A B C D E
1 n<=0 a[0]_a[n]<0 sub<a[i] max1<sub i<n
2 n>0 a[i]>0 sub>=a[I] max1>=sub i>=n

n=0;A1
n=6,a[]={-2,11,-4,13,-5,-2};A2,B2,C1,C2,D1,D2,E1,E2
n=6,a[]={-2,-11,-4,-13,-5,-2};A2,B1

單元測試代碼

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../2/head.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:
        TEST_METHOD(TestMethod1)
        {
            int n = 6;
            int num[] = { -2,11,-4,13,-5,-2 };
            Assert::AreEqual(MAX(n, num), 20);
        }
        TEST_METHOD(TestMethod2)
        {
            int n = 6;
            int num[] = { -2,-11,-4,-13,-5,-2 };
            Assert::AreEqual(MAX(n, num), 0);
        }
        TEST_METHOD(TestMethod3)
        {
            int n = -1;
            int num[] = { -2,11,-4,13,-5,-2 };
            Assert::AreEqual(MAX(n, num), 0);
        }
    
    };
}

測試結果圖
技術分享圖片

最大連續子數組和(最大子段和)及其條件覆蓋