最大連續子數組和(最大子段和)ios
問題: 給定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。
-- 引用自《百度百科》git
遞推法:在對於上述分治算法的分析中咱們注意到,若記b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,而且i<=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算法
https://dev.tencent.com/u/yang_gang/p/ruanjiangongchengdisancizuoye/git 數組
代碼以下測試
#include <iostream> #include "text.h" using namespace std; class myclass { public: myclass(int n) { i = n; }; void input(); int max(); int a[100], i; }; void myclass::input() { int j = 0; for (j; j < i; j++) { cin >> a[j]; } }; int myclass::max() { int b[100]; int max1; int j; b[0] = a[0]; max1 = b[0]; for (j = 1; j < i; j++) { if (b[j - 1] > 0) { b[j] = a[j] + b[j - 1]; } else b[j] = a[j]; if (b[j] > max1) max1 = b[j]; } if (max1 < 0) return max1 = 0; else return max1; }; void main() { int i, max; cin >> i; myclass a(i); a.input(); max = a.max(); cout << max; while(1); }
採用條件覆蓋的方法。
應知足如下覆蓋狀況:
斷定一:n>0,n<=0
斷定二:b[j]>0,b[j-1]<=0
斷定三:max>b[j],max<=b[j]
斷定四:j>i,J<=i
斷定五:max>0,max<=0
設計以下測試用例
(1)沒有數,max=0;
(2)全是負數,-2,-2,-4,-3,-5,-2,max=0;
(3)通常狀況,-2, 11, -4, 13, -5, -2, max=20;
(4)全是正數,2,2,4,3,5,2 max=18;
代碼以下spa
TEST_CLASS(UnitTest1) { public: TEST_METHOD(TestMethod1) { // 通常狀況 myclass test(6); test.a[0] = -2; test.a[1] = 11; test.a[2] = -4; test.a[3] = 13; test.a[4] = -5; test.a[5] = -2; Assert::AreEqual(test.max(), 20); }; TEST_METHOD(TestMethod2) {//沒有數 myclass test(0); Assert::AreEqual(test.max(), 0); }; TEST_METHOD(TestMethod3) {//全是負數 myclass test(6); test.a[0] = -2; test.a[1] = -2; test.a[2] = -4; test.a[3] = -3; test.a[4] = -5; test.a[5] = -2; Assert::AreEqual(test.max(), 0); }; TEST_METHOD(TestMethod4) {//全是正數 myclass test(6); test.a[0] = 2; test.a[1] = 2; test.a[2] = 4; test.a[3] = 3; test.a[4] = 5; test.a[5] = 2; Assert::AreEqual(test.max(), 18); }; };