1. 程式人生 > >求最大字段和

求最大字段和

動態規劃 max include public 利用 http col https 通過

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。

流程圖如下:

主流程圖:

技術分享圖片

核心算法流程如下:
技術分享圖片

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編輯器的應用和單元測試的要點,為我們以後打下了堅實的基礎,除此之外我們還學會了幾種單元測試的覆蓋情況,我們通過不斷地交流和查詢,使我們的合作能力得到了進一步的加強,我們成長了很多,希望我們都可以更進一步。

求最大字段和