整數順序檔案查詢至少出現兩次的整數

2021-06-18 13:14:53 字數 1491 閱讀 8774

《programming pearls》

2.2 給定包含4300000000個32位整數的順序檔案,如何找出乙個出現至少兩次的整數?

【方法一】

思路:考慮兩個條件

1.所有的整數都儲存在順序檔案中,因此,讀取檔案的次數將明顯影響演算法的效率;

2.順序檔案中包含的整數個數為4300000000,如果全部讀取放在記憶體中的話,必須要考慮記憶體空間因素。

解決方案:

由上面的問題,想到了bit-map,可以申請537500000個char型陣列,陣列中每個位對應4300000000個整數中的乙個數,剛開始時,將所有的位都置為0,如果有存在相對應的數,那麼對應的位就置為一。

問題又出來了,如何才能表示至少包含兩次的整數呢?

這時,我們發現,要表示至少包含兩次的整數,僅用一位來表示是不夠的。那麼用兩位呢?00表示沒有資料,01表示存在乙個,10表示存在兩個,11表示存在兩個以上。

這樣,需要申請大小為1075000000的char型別的陣列,兩位對應乙個數。

初始時,所有位都置0,然後開始讀取順序檔案,讀到整數後,相應的位做相應的改變。

這樣,我們便只需要一次操作,而且使用了最少的記憶體便解決這個問題了。

【方法二】

binarysearch

不是對檔案內容折半,而是對搜尋範圍折半。由於4.3g>32位的整數空間,根據鴿籠原理一定會有重複的整數。搜尋範圍從所有的32位正整數開始(全部當成unsigned int,簡化問題),即[0,2^32),中間值即為2^31。然後遍歷檔案,如果小於2^31的整數個數大於2^31,則調整搜尋範圍為[0,2^31],反之亦然;然後再對整個檔案遍歷一遍,直到得到最後的結果。這樣一共會有logn次的搜尋,每次過n個整數(每次都是完全遍歷),總體的複雜度為o(nlogn)。

例子:陣列[4,2,5,1,3,6,3,7,0,7],假定從3位的整數空間內搜尋。第一次的範圍為[0,8),遍歷後發現[0,4)範圍內的個數為5,於是調整為搜尋[0,4)範圍內的整數。第二次發現[2,4)範圍內的整數為3,大於2,於是調整為[2,4)。再經過第三次的遍歷,找出3為重複出現的整數。

改進:上面的辦法有很多的冗餘。於是提出了乙個辦法:建立乙個新的檔案(是順序檔案就可以)。在一次遍歷過後確定搜尋的範圍後,把原有檔案裡這個範圍內的整數寫到新的檔案裡去,下次搜尋就只要搜尋這個檔案了。這樣可以近似線性的複雜度(但是常數項應該很大)。

【方法三】

若整數是排好序的,乙個線性查詢的解法

/**

* 問題描述:

* 給定包含4 300 000 000個32位整數的順序檔案,

* 如何找出乙個至少出現兩次的整數

* * @author loo

* */

public class findtwice ;

int icount=0;

int increase=arr[0]; // suppose=arr[0];

for(;icounticount+increase)

if(arr[icount]

43億整數中查詢至少出現2次整數

問題 在43億整數中查詢至少出現2次整數 方法 比較大的資料處理,第一時間想到位儲存 1 2 32 4gb 4294967296 小於43億,所以說必定有重複的整數 2 儲存2 32 4gb 的位資料 需要2 32 1024 2 8 512m記憶體 3 按套路來,首先開闢512m 1記憶體,清零 查...

40億個非負整數中找到出現兩次的數和中位數

問題 現有40億個32位的無符號整數 0 4294967295 可以最多使用1gb,找出出現兩次的數 補充問題 最多用10mb,找到中位數 思路 問題一 可以申請乙個長度為 4294967295 2 的bitmap,用兩個位置表示乙個詞頻,首次遇到數num,則bitarr num2 1 和bitar...

查詢乙個字串中第乙個只出現兩次的字元。

題目 查詢乙個字串中第乙個只出現兩次的字元。比如 abcdefabcdefabc 中第乙個只出現兩次為 d 要求時間複雜度為o n 空間複雜度為o 1 由於本體的特殊性,我們可以定義乙個非常簡單的雜湊表。字元 char 是乙個長度為8的資料型別,因此總共有256中可能。於是我們建立乙個長度為256的...