原文的大意是這樣的,要求寫乙個二分查詢演算法,並且當要查詢的數出現不止一次時,返回最後那個數的下標。然後給你一段有錯的**,請你改。
這段有錯的**是這樣的(我作了簡化):
文中指出了**中的錯誤,一是第7行(l+u)可能溢位,二是當程式執行到l=u-1時,計算出的m就與l相等,如果這時不幸地第8行的條件成立,那麼就會進入死迴圈,因為這次迭代沒有改變l和u的值,無論再迭代多少遍也不會了。
這兩點分析都很正確,但接下來作者給出的修改版本,不僅完全不是在上面**的基礎上改,而且給出的**邏輯複雜、混亂,缺乏一致性。
下面我將分析上面這段有錯**,給出自己的修改,然後再分析作者給出的版本。
上面**的思想是清晰的,維護乙個迴圈不變式:如果要找的數存在的話,它下標一定在區間[ l , u ]中,然後通過迭代,不斷縮小區間,直到退化成乙個點,最後檢測這個點是不是目標值。迴圈體中對不變式的維護都沒有錯。問題就是怎樣避免第8行的把m直接賦給l。題目要求返回最後乙個滿足的數,所以在迴圈體中,當檢測到相等時,一不能立刻就返回,二不能縮減區間的後半段。要維護這樣乙個不變式,這個賦值在所難免。我能想到的唯一的辦法就是,當l=u-1時,就退出迴圈,然後先後檢查此時的a[u]和a[l]。
所以我的修改是這樣的:
接下來,我要分析一下作者的修改,他的**大意是這樣的,注釋我沒改動:
我們先無視注釋,我完全搞不懂注釋,文中也不解釋清楚。從迴圈體的if-else語句判斷,他要維護的不變式是考察區間[l, u),注意是「左閉右開」,要找的數下標一定在這個區間內,如果存在的話。而看他對區間端點的賦初值,u=e,把a[e]給排除在外了。那要找的數就是a[e]怎麼辦呢?他有這條語句把關呢,if (a[u] == v) return u;後面還十分堂皇地加了注釋。其實如果初值正確的話,只需要檢測a[l]即可,因為a[u]這個值根本不在我們要考察的區間裡。
所以我對作者的版本的改法是:
我記得《程式設計珠璣》上對這類問題有過討論的。
程式設計之美 第三章 結構之法 3 11程式改錯
程式改錯 找出乙個有序字串陣列arr中值等於字串v的元素的序號,如果有多個元素滿足這樣的條件,則返回其中序號最大的 程式中的錯誤 1 midindex minindex maxindex 2 這樣可能會由於求和中間結果而溢位,應該改為midindex minindex maxindex minind...
Python程式設計之美 初識GUI程式
首先,學習python,要了解它的歷史 現在和未來 知道它的應用範圍,學以致用 理解她的格言,深體味 there should be one and preferably only one obvious way to do it.tim peters 大體意思是,什麼事情都應該有乙個,而且最好只有...
讀書筆記 程式設計之美(一
不得不說程式設計之美是一本很有意思的書,裡面的各式各樣新奇的問題,總是可以通過課上講的簡單的問題來解決,對於訓練自己的思維的確有很大的好處。一般解決複雜的問題,我們總是可以通過 1 畫圖 鍊錶 二叉樹,2 舉例,3 分解 分治法 動態規劃來解決。for 遍歷a的位置 遍歷b的位置 判斷a b的位置組...