10G整數檔案中尋找中位數

2021-06-09 04:43:58 字數 1495 閱讀 7078

from:  

題目:在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可(記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體)。

關於中位數:資料排序後,位置在最中間的數值。即將資料分成兩部分,一部分大於該數值,一部分小於該數值。中位數的位置:當樣本數為奇數時,中位數=(n+1)/2 ; 當樣本數為偶數時,中位數為n/2與1+n/2的均值(那麼10g個數的中位數,就第5g大的數與第5g+1大的數的均值了)。

分析:既然要找中位數,很簡單就是排序的想法。那麼基於位元組的桶排序是乙個可行的方法

思想:將整形的每1byte作為乙個關鍵字,也就是說乙個整形可以拆成4個keys,而且最高位的keys越大,整數越大。如果高位keys相同,則比較次高位的keys。整個比較過程類似於字串的字典序。

第一步:把10g整數每2g讀入一次記憶體,然後一次遍歷這536,870,912個資料。每個資料用位運算">>"取出最高8位(31-24)。這8bits(0-255)最多表示255個桶,那麼可以根據8bit的值來確定丟入第幾個桶。最後把每個桶寫入乙個磁碟檔案中,同時在記憶體中統計每個桶內資料的數量,自然這個數量只需要255個整形空間即可。

代價:(1) 10g資料依次讀入記憶體的io代價(這個是無法避免的,cpu不能直接在磁碟上運算)。(2)在記憶體中遍歷536,870,912個資料,這是乙個o(n)的線性時間複雜度。(3)把255個桶寫會到255個磁碟檔案空間中,這個代價是額外的,也就是多付出一倍的10g資料轉移的時間。

第二步:根據記憶體中255個桶內的數量,計算中位數在第幾個桶中。很顯然,2,684,354,560個數中位數是第1,342,177,280個。假設前127個桶的資料量相加,發現少於1,342,177,280,把第128個桶資料量加上,大於1,342,177,280。說明,中位數必在磁碟的第128個桶中。而且在這個桶的第1,342,177,280-n(0-127)個數字上。n(0-127)表示前127個桶的資料量之和。然後把第128個檔案中的整數讀入記憶體。(平均而言,每個檔案的大小估計在10g/128=80m左右,當然也不一定,但是超過2g的可能性很小)。

代價:(1)迴圈計算255個桶中的資料量累加,需要o(m)的代價,其中m<255。(2)讀入乙個大概80m左右檔案大小的io代價。

注意,**的情況下,這個需要讀入的第128號檔案仍然大於2g,那麼整個讀入仍然可以按照第一步分批來進行讀取。

第三步:繼續以記憶體中的整數的次高8bit進行桶排序(23-16)。過程和第一步相同,也是255個桶。

第四步:一直下去,直到最低位元組(7-0bit)的桶排序結束。我相信這個時候完全可以在記憶體中使用一次快排就可以了。

整個過程的時間複雜度在o(n)的線性級別上(沒有任何迴圈巢狀)。但主要時間消耗在第一步的第二次記憶體-磁碟資料交換上,即10g資料分255個檔案寫回磁碟上。一般而言,如果第二步過後,記憶體可以容納下存在中位數的某乙個檔案的話,直接快排就可以了。

10G個數找中位數

題目 在乙個檔案中有 10g 個整數,亂序排列,要求找出中位數。記憶體限制為 2g。只寫出思路即可 記憶體限制為 2g的意思就是,可以使用2g的空間來執行程式,而不考慮這台機器上的其他軟體的占用記憶體 關於中位數 資料排序後,位置在最中間的數值。即將資料分成兩部分,一部分大於該數值,一部分小於該數值...

Oracle控制檔案 10g

作用 二進位制檔案 記錄了資料庫當前例項的結構和行為,資料檔案日誌檔案的資訊,維護資料庫一致性 引數檔案中定義了控制檔案的位置和大小 很小的二進位制檔案,一般不超過100m mount階段open以後,一直在用 一套控制檔案只能連線乙個database 分散放置,至少乙份,至多八份 相關檢視 v c...

7 4 中位數 10分

乙個有 n 個整數的陣列 a,n是乙個奇數。每次可以選擇陣列裡的乙個元素 a i 並把這個元素加上 1。在至多 k 次操作之後,陣列的中位數最大能變成多少。多組輸入 第一行兩個整數 n,k 1 n 2 10 5 1 k 10 9 第二行 n 和整數 a 1 a 2 a n k 次操作後陣列的中位數。...