1. 程式人生 > >學習筆記——c語言實現最大連續子序列之和的演算法

學習筆記——c語言實現最大連續子序列之和的演算法

今天到圖書館借了本資料結構的書,翻開一看,原來這裡有我之前參加的周立功機試的題目,哎,真是後悔莫及啊!現在把這個問題好好總結一下,以備不時之需。

最大連續子序列之和問題:給出N個整數(可以為負)A1A2A3,…,An,找出ij項之和的最大值,如果所有整數為負,最大值為0

下面是給出了三種不同的演算法。

//*********************************************************************************************

#include <stdio.h>

static int Start = 0;

static int End = 0;

/*

該演算法是窮舉法,時間複雜度為O(n^3).第一二層迴圈迭代了所有肯能的連續子序列,第三層迴圈裡tempSum += a[n]就是計算各子序列的和。然後tempSum再與max作比較,求出終結果。StartEnd分別記錄了子序列的起始和終止位置(陣列下標從0開始算)。

*/

int fun(int a[], int n)//n是陣列元素的個數

{

int i,j,k,tempSum;

int max = 0;

for (i = 0; i < n; i++)

for (j = i; j < n; j++)

{

tempSum = 0;

for (k = i; k <= j; k++)

{

tempSum += a[k];

}

if (tempSum > max)

{

max = tempSum;

Start = i;

End = j;

}

}

return max;

}

/*

該演算法是基於上一個演算法的改進,演算法的時間複雜度為O(n^2).在這演算法中去掉了上面那個

演算法的第二層迴圈,原因在於,從a[i]加到a[j]tempSum等於a[i]加到a[j-1]tempSum

,所以就沒必要在來一層迴圈重新算tempSum了。

*/

int fun2(int a[], int n)

{

int i,j,tempSum;

int max = 0;

for (i = 0; i < n; i++)

{

tempSum = 0;

for (j = i; j <= n; j++)

{

tempSum += a[j];

if (tempSum > max)

{

max = tempSum;

//Start = i;

//End = j;

}

}

}

return max;

}

/*

該演算法是線性演算法。我們在計算最大連續子竄的時候會發現一個規律:a[i]a[j]之和sum

若小於零,那麼a[j]後面的項再與sum相加的和一定小於沒有加上sum之前的和大。根據這個我們可以設計出如下演算法。

*/

int fun3(int a[], int n)

{

int i,j;

int max = 0;

int tempSum = 0;

for (i = 0,j = 0; j < n; j++)

{

tempSum += a[j];

if (tempSum > max)

{

max = tempSum;

//Start = i;

//End = j;

}

else if (tempSum < 0)//tempSum小於0,下次直接從第j+1項開始加

{

i = j + 1;

tempSum = 0;

}

}

return max;

}

int main()

{

int a[10] = {1,-2,4,6,-2,4,-6,8,-2,-4};

printf("start:%d,end:%d,sum:%d/n", Start,End,fun(a,10));

printf("fun2: sum = %d/n", fun2(a,10));

printf("fun3: sum = %d/n", fun3(a,10));

return 0;

}

//*******************************************************************************************