程式設計珠璣 第八章 演算法設計技術

2021-08-26 21:47:21 字數 2719 閱讀 4372

一,概述

問題:求一維陣列中連續子向量的最大和。

例如:a[6]=; 則最大連續子向量的和 為 10+8 = 18

1)解法一:簡單演算法

#include #define max(a, b) ((a)>(b)?(a):(b))

int main()

; int i,j,k;

int sum=0;

int maxsofar=0;

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

maxsofar=max(maxsofar,sum);

} }printf("max=%d\n",maxsofar);

return 0;

}

2)兩個平方演算法

演算法一:

#include #define max(a, b) ((a)>(b)?(a):(b))

int main()

; int i,j;

int sum=0;

int maxsofar=0;

for(i=0;i<6;++i) }

printf("max=%d\n",maxsofar);

return 0;

}

演算法二:

#include #define max(a, b) ((a)>(b)?(a):(b))

int main()

; int cumarr[6]; cumarr[-1]=0;

int i,j;

int sum=0;

int maxsofar=0;

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

for(i=0;i<6;++i) }

printf("max=%d\n",maxsofar);

return 0;

}

3)分治演算法

思想:以m為分界線,最大值有三種情況

一:在m左側

二:在m右側

三:跨越m

關鍵:最初求解左右最大值時候,一定要從中間向兩側遞增。看原始碼解釋……

#include "stdio.h"

#define max(a,b) a>b?a:b

int a[6]=;

int max2(int a,int b,int c)

int maxsum(int l,int u)

printf("m=:%d\n",m);

rmax =sum =0;

for(i=m+1;i<=u;++i)

return max2(lmax + rmax , maxsum(l,m) , maxsum(m+1,u) );

}int main()

【注意】 max2() 如果用巨集 #define max(a,b,c) max(a,b) >c?max(a,b):c 則不會得到正確結果

4)掃瞄演算法

#include "stdio.h"

int main()

; int i,sum=0;

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

printf("max=%d",sum);

return 0;

}

二,總結

優化演算法的策略

1)儲存已經計算的狀態,避免重複計算。

2)將資訊預處理到資料結構中。例如演算法二

3)分治演算法,採取更高階的演算法

4)掃瞄演算法,巧妙

5)下界:證明某個匹配的下界,確定最優演算法

三,習題

10)可以採用兩種方法:o(n*n)

#include #define min(a, b) ((a)>(b)?(b):(a))

#define obs(a) a>0?a:-a

int main()

; int i,j,k;

int sum=0;

int maxsofar=65535;//這個很關鍵

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

maxsofar=min(maxsofar,obs(sum));

} }printf("max=%d\n",maxsofar);

return 0;

}

返回結果是 1

可以採用o(nlogn)的演算法

#include #define min(a, b) ((a)>(b)?(b):(a))

#define obs(a) a>0?a:-a

/*先將 軸 記錄在temp 中 先從後面向前找小於軸的 放到第乙個(即軸所在位置)

再從前向後找 大於軸的元素 存放到 上一步找到的小於軸的位置

總之:要做的是將後面小於軸的 跟 前面大於軸的 做替換 】

當退出while 迴圈後 因為最後收場的是 i從低端加上來 所以 i 的位置對應 軸最後要存放的位置*/

int partition(int a,int i,int j)

a[i]=temp;//軸的位置

return i;

}void quicksort(int a,int i,int j)

{ int p;

if(i

返回結果是 1

13)最大子陣列問題,給定n*n陣列,求矩形子陣列的最大總和。

詳見部落格:

程式設計珠璣第八章 演算法設計技術

本章就乙個小問題研究了四種不同的演算法,重點強調了這些演算法的設計技術,綜合本章內容,告訴我們 複雜深奧的演算法有時可以極大地提高程式效能。問題定義 具有n個浮點數的向量x,求出輸入向量的任何連續子向量的最大和。立方演算法 maxsofar 0 for i 0,n for j i,n sum 0 f...

程式設計珠璣第八章 演算法設計技術

首先思考乙個問題,給定乙個含有n個元素的vector,找出其中最大的子向量 即所有元素之和為最大值 如果是都為正數,那麼問題變得十分簡單,整個vector即是最大子向量,但是如果是正數負數混合的形式呢?問題將變得複雜,接下來將簡要介紹幾種演算法的思路。其複雜度由最初的立方演算法降低到最終的線性演算法...

《程式設計珠璣》學習記錄第八章演算法設計技術

演算法的設計這個問題太過龐大,對於乙個程式設計師來說,最好的辦法就是多接觸不同的演算法,並且時刻總結。問題 乙個一維的整數陣列,有n個元素,元素有正數也有負數。找到陣列中任意連續個元素最大和。方法一 使用暴力法找到所有的子串行,並計算出所有子串行的和,結果自然就得到了。這種方法的事件複雜度是o n ...