編程珠璣-第二章問題A

題目:給定一個包含40億個隨機排列的順序文件,找到一個不在文件中的32位整數,在有足夠內存的情況下應該如何解決該問題?如果有幾個外部的臨時文件可用,但是僅有幾百字節的內存,又該如何解決?

首先40億=40X10^8 = 4X10^9 ~= 4G,故40億個隨機數,即使數字都不同,也是少於32位的能表示的最大不同數字的個數的,所以必然是缺少數字的。

(1)有足夠內存的情況

對於有足夠內存的情況,完全可以採用第一章介紹的位圖方法,每一位表示第一數字,那2^32需要2^24字節,即16M內存。

(2)僅有幾百字節內存和幾個稀疏順序的文件

二分思想:根據二進制數某一位是0還是1,可以分成兩部分。

由於只有幾百字節的內存和幾個稀疏的順序文件,我們可以先對40億的數據進行分類,當分成的剩餘文件可以用幾百字節解決時,我們就可以用位圖法了。

先從高位開始,對數據進行分類,根據0,1分成兩部分,此時有兩種情況:

  • 兩部分數據個數相同
  • 兩部分數據個數不同

當數據個數不同時,對數據少的那部分再進行二分,當數據個數相同時,則隨機選擇一個進行二分。

下面舉個例子:

問題的關鍵是隻要找一個數字,那麼我們把問題簡化一下,給定一個文件,裏頭最多包含16個4bit的整數,找到一個不在文件中的4bit整數。假設這十個數是 

1 2 3 4 5 7 6 9 8 10。
根據最高位是0,1可以分爲兩部分

1,2,3,4,5,6,7

8,9,10

那我們接着對8,9,10進行二分,根據次高位是0,1進行分類。

當10個數字是1,2,3,4,5,8,9,10,11,12時,此時分成兩部分後都是5個數,隨機選擇一部分進行二分。

當數字中有重複數字時呢?

1,1,1,1,1,1,1,1,1,2,7,8,8,8

此時14個數時,二分後,一個包含11個數,一個包含3個8,我們選擇小的組,進行再分,也是正確的。


總結:

此題用二分的思想,很巧妙在對內存有限制的情況下,能夠對大量數據進行處理,巧妙的運用了二分思想,此處的二分是對某一位進行分類,從而達到減小處理數據的大小的目的

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