最大字段和各种不同算法实现(参考编程珠玑)
生活随笔
收集整理的這篇文章主要介紹了
最大字段和各种不同算法实现(参考编程珠玑)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
求最大字段和的算法很好的講解了算法設計技術。根據《編程珠璣》上的描述,簡單實現各種不同的算法。如下:
1、最簡單的方法:對所有滿足0≤i≤j<n的(i,j)整數進行迭代。對每個整數對,都計算x[i..j]的總和:
簡單方法 int maxSum_easy(int n, int* a, int& besti, int& bestj) //最簡單的方法,復雜度為O(n^3) {int maxSoFar = 0, i = 0, j = 0, k = 0, sum = 0;for (i = 0; i < n; ++i)for ( j = i; j < n; ++j){sum = 0;for (k = i; k<=j; ++k)sum += *(a+k);if (sum > maxSoFar){maxSoFar = sum;besti = i;bestj = j;}}return maxSoFar; }2、改進簡單的方法,將復雜度變為O(n2),注意子和求解過程,分別有兩種改進方法:
方法一,如下:
方法二,如下:
改進二 int maxSum_O2nb(int n, int *a, int& besti, int& bestj) //增加一累加數組,時間復雜度變為O(n^2) {int maxSoFar = 0, i = 0, j = 0, sum = 0;int * acc = new int[n+1]; //創建一個額外的累加器*(acc) = 0;for (i = 1; i <= n; ++i)*(acc+i) = * (acc+i-1) + *(a+i-1);for (i = 0; i < n; ++i)for (j = i; j < n; ++j){sum = *(acc+j+1) - *(acc+i); // sum is sum of a[i..j]if (sum > maxSoFar){maxSoFar = sum;besti = i;bestj = j;}}delete acc;return maxSoFar; }3、同時,還可以利用分治法對其進行求解,復雜度為O(nlogn)代碼如下:
分治法求解 int maxSum_ConDiv(int *a, int left, int right)//分治法,復雜度為O(nlogn),調用形式為maxSum_ConDiv(a,0,n-1) {int maxSoFar = 0, sum = 0, i = 0, m = (left+right)/2, lmax =0, rmax = 0, lsub = 0, rsub =0;if (left > right) //zero elementsreturn 0;if (left == right) //one elementreturn left > 0 ? left : 0;for (i = m; i >= left; --i){sum += *(a+i);if (sum > lmax)lmax = sum;}sum = 0;for (i = m+1; i <= right; ++i){sum += *(a+i);if (sum > rmax)rmax = sum;}//find max value among the 3 values and return itlsub = maxSum_ConDiv(a,left,m);rsub = maxSum_ConDiv(a,m+1,right);maxSoFar = lmax + rmax;if (lsub > maxSoFar)maxSoFar = lsub;if (rsub > maxSoFar)maxSoFar = rsub;return maxSoFar; }4、另外一種方法,是效率最高的,復雜度為O(n),利用了動態規劃的思想,代碼如下:
動態規劃求解 int maxSum_sm(int* a, int n) //掃描算法,時間復雜度為O(n) {int maxSoFar = 0, maxendinghere = 0, i =0, temp =0;for (; i < n; ++i){maxendinghere = maxendinghere+a[i];maxendinghere = maxendinghere > 0 ? maxendinghere : 0;if (maxendinghere > maxSoFar)maxSoFar = maxendinghere;}return maxSoFar; }測試實驗如下所示:
int main() {int a[] = {31, -41, 59, 26, -53, 58, 97, -93, -23, 84},n, besti = 0, bestj = 0, maxSum = 0;n = sizeof(a)/sizeof(a[0]);cout << "a的最大子和為:" << maxSum_sm(a,n) << endl;//cout << ";是 " << besti << "->" << bestj << "的和" << endl;return 0; }?
轉載于:https://www.cnblogs.com/lyfruit/archive/2013/04/15/3021317.html
總結
以上是生活随笔為你收集整理的最大字段和各种不同算法实现(参考编程珠玑)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 2.6 内核定时器
- 下一篇: hibernate---一对一单项外键关