關於《編程珠璣》中一個找出一個不存在的數的問題的探討


         《編程珠璣》第二章2.1的三個問題中,有個問題是這樣的:
         給定一個最多包含40億個隨機排列的32位整數的順序文件,找出一個不在文件中的32位整數(在文件中至少缺失一個這樣的數——爲什麼?)。
1、如果有足夠的內存,如何處理?
2、如果內存不足,僅可以用幾個外部的臨時文件來進行處理,如何處理?
         主要關注第二個問題,在僅有幾百個字節的內存下,如何藉助外部的“臨時”文件解決該問題?
         第二章主要對於二分法進行研究,故使用二分法,給了我們一個很好的答案。

         
          寫的很清楚了,從第一位開始探測,根據是0或1進行分組,對包含的整數個數不大於N/2的序列繼續進行探測,只要搜索到某個位數時,有個分組爲的整數個數爲0,那麼便成功找到缺少的數。
         考慮一個極端情況,以對3位的整數進行查找爲例。
         有如下8個3位的整數:0、1、2、3、4、4、6、7。

         以二進制表示是:

000

001
010

011
100
100
110
111

         若用以上方法:則會造成探測第一位的時候,有4個0、4個1,按照以上說法“第二趟最多讀取n/2=4個元素”可見,0是符合的,所以,進入第一位爲0的4個整數中進行搜索,於是,導致第一步就走錯了…
         要探測該序列,在探測第一位時,發現分組個數一樣,故無法進行捨棄;在探測第二位時仍需探測全部的8個數,而探測第二位時,0與1的個數仍相同,也無法捨棄;最終只能通過末位進行判定,而對末位,即使知道了有3個是0,5個是1,缺少的是以0結尾的數,也無法確切的知道整個整數是什麼,因爲第1、2位都無法確定應是1或0.
         之所以會有這種情況,是因爲在處理倒數第N位時,
         1、 有大於等於2的N次方個數
         2、 根據0或1進行分組時,分組包含的數字個數一樣,且有個分組包含了所有的01序列組合。(如上面的倒數第三位爲0的序列)。
         於是,導致無法進行縮減,若運用作者提供的方法,則很有可能會出現錯誤。


         回到原題,若判定的後N位數,恰好是這樣的情況,該當如何?


解決:若有這種情況,壓根不會進入這個一類中探測。可以模擬一個4位數的數列嘗試。

如果一個序列的後N位至少含2的N次方個不相同的數,那麼倒數第n+1位(不論是0或1)的這一類至少有2的n次方個整數,則定不會選擇該類繼續(若選擇該類,說明另一類含有的整數數量不小於他,那麼總數一定大於2*2的n次方個,不合題意),故選擇到的一類,定是缺了某個數的一類。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章