程式設計珠璣讀後感1 1個演算法

2021-04-08 16:35:19 字數 2314 閱讀 9007

在《程式設計珠璣》第八章,作者提出一道演算法題:

程式描述:

輸入是乙個具有n個浮點數字的向量x: 其輸出是在輸入的任何相鄰子向量中找出的最大和。

例如,輸入如下10個元素:

31 -41 59 26 -53 58 97 -93 -23 84

返回 x[2..6]的總和,或為187

作者分別給出了三次演算法o(n^3),兩個二次演算法o(n^2),分治演算法o(n logn )和掃瞄演算法o(n)。

我對該問題作了研究後,給出自己的一種解法。

考慮陣列 x[ n ],我們新開闢乙個陣列sumx[ n + 1 ],其中sumx[ 0 ] = 0, 而 sumx[ i ] 為 x[ 0..i-1 ] 的和。

這樣,對於 x[ i..j ]的和,有 sum( x[ i..j ] ) = sumx[ j+1 ] - sumx[ i ].

對於陣列sumx, 假設最大值為 sumx[ po**ax ], 最小值為 sumx[ po**in ],下面分三種情況:

1. po**in < po**ax,也即最小值在最大值左邊,我們可以肯定 x[ po**in..po**ax-1 ] 就是所要求的總和。

否則,若x[ i..j ]是所要求的總和,且 i != po**in或 j != po**ax,

則有sum( x[ i..j ] ) <= sum( x[ po**in, j ] ) <= sum( x[ po**in, po**ax ] )

或sum( x[ i..j ] ) <= sum( x[ i, po**ax ] ) <= sum( x[ po**in, po**ax ] )

上面兩不等式至少有乙個嚴格小於,所以sum( x[ i..j ] ) < sum( x[ po**in, po**ax ] )

由上可知,這種情況中返回結果 sumx[ po**ax ] - sumx[ po**in ]

2. po**in == po**ax,說明除了 x[ po**in ]外,其餘x[ i ] 全為0

又由於sumx[ 0 ] = 0,所以 sumx[ po**ax ] > 0

所以 x[ po**ax - 1 ]是所要求的總和

這種情況中返回結果 sumx[ po**ax ],也就是 x[ po**ax-1 ] 乙個元素

3.po**in > po**ax

這種情況比較複雜,我們可以把sumx分為三部分:

a)sumx[ 0 ]..sumx[ po**ax ];  b)sumx[ po**ax + 1 ] ... sumx[ po**in - 1 ], c)sumx[ po**in ].. sumx[ n + 1 ].

我們可以肯定,要找出的x[ i..j-1 ],也可以認為是sumx[ i],sumx[j ]必在同乙個小部分中。

否則,若 0 <= i <= po**ax 而 po**ax < j

則sum( x[ i..j-1 ] ) = sumx[ j ] - sumx[ i ] < sumx[ po**ax ] - sumx[ i ]。

對於其他情況,也可以同樣證明。

於是我們可以分別對陣列a,b,c處理,找出最大和。

對陣列a,找出最小值sumx[ po**in1 ],必有po**in1 < po**ax,

於是結果 tmpmax1 = sumx[ po**ax ] - sumx[ po**in1 ]

對陣列c,找出最大值sumx[ po**ax3 ],必有po**in < po**ax3,

於是結果 tmpmax3 = sumx[ po**ax3 ] - sumx[ po**in ]

對陣列b,這是乙個比開始問題規模更小的子問題,可再迭代處理,得到結果tmpmax2

這種情況中返回結果 tmpmax1, tmpmax2, tmpmax3中最大值

這種演算法在最優情況下(po**in <= po**ax)可看作一線性演算法,執行時間o(n)

在最壞情況下(每次處理均有po**ax = 0, po**in = 陣列索引最大值,每個子問題規模減2),

這時可看作二次演算法,執行時間o(n^2)

使用隨機數除錯,發現大部分情況執行時間在o( n logn ) 與 o( n^2 )之間。

測試結果:

n=10  n*logn=23  n*sqrtn=31  n^2=100  程式執行次數:27

n=100  n*logn=460  n*sqrtn=1000  n^2=10000  程式執行次數:404

n=1000  n*logn=6907  n*sqrtn=31622  n^2=1000000  程式執行次數:13009

n=10000  n*logn=92103  n*sqrtn=1000000  n^2=100000000  程式執行次數:683867 

程式設計珠璣讀後感

第二章則又提出了三個問題,提到了二分查詢的廣泛應用,打破了對二分查詢的狹隘理解,以及一種旋轉向量的巧妙演算法 感覺用到了數論的一些知識 感覺最巧妙的還是對與查詢字典中所有變形詞集的巧妙解法,其採用利用簽名歸類的方法,然後對簽名進行排序,我之前從來沒有遇到過,感覺十分新奇。第三章講了一些資料結構的技巧...

《C程式設計》讀後感

c程式設計 讀後感 網上很多人評價這書不高,其實從內心裡講,是這本書帶領我入門的。我說的是譚浩強先生的書。這本書講得很細,而且知識的銜接也做得很好。我以這本書為重點,再以其它的c語言教程為輔,終於算是入了c語言的門。如果能讓我再從頭學習的話,我一定是認真的讀這本教材,再把c的標準庫的原始碼作為閱讀材...

《程式設計實踐》讀後感

程式設計實踐 讀後感 昨天晚上讀這本書,重點讀資料結構這一章,也許是因為讀gawk101原始碼有一段時間,在重讀時,感覺作者寫得真好。我重點放在書中的 上,發現那些 寫得像珍珠一樣,真是漂亮。作者寫了鍊錶,然後再寫乙個遍歷鍊錶的函式,因為遍歷鍊錶時,可能是要列印,可能是要統計元素個數,可能是要找某個...