大資料的排序問題

2021-06-21 16:59:54 字數 2245 閱讀 6843

楔子:問題:假設乙個檔案中有9億條不重複的9位整數,現在要求對這個檔案進行排序。

一般解題思路:1、將資料匯入到記憶體中 2、將資料進行排序 (比如插入排序、快速排序) 3、將排序好的資料存入檔案

難題:乙個整數為4個位元組即使使用陣列也需要900,000,000 * 4byte = 3.4g記憶體對於32位系統,訪問2g以上的記憶體非常困難,而且一般裝置也沒有這麼多的物理記憶體將資料完全匯入到記憶體中的做法不現實。

其他解決辦法:1、匯入資料庫運算 2、分段排序運算 3、使用bit位運算

解決方案一:資料庫排序將文字檔案匯入到資料庫,讓資料庫進行索引排序操作後提取資料到檔案

優點:操作簡單缺點:運算速度慢,而且需要資料庫裝置。

解決方案二:分段排序操作方式:規定乙個記憶體大小,比如200m,200m可以記錄52428800條記錄,我們可以每次提取5000萬條記錄到檔案進行排序,要裝滿9位整數需要20次,所以一共要進行20次排序,需要對檔案進行20次讀操作

缺點:編碼複雜,速度也慢(至少20次搜尋)

關鍵步驟:先將整個9位整數進行分段,億條資料進行分成20段,每段5000萬條,在檔案中依次搜尋0~5000萬,50000001~1億…… 將排序的結果存入檔案

解決方案三:bit位操作思考下面的問題: 乙個最大的9位整數為999999999 這9億條資料是不重複的,可不可以把這些資料組成乙個佇列或陣列,讓它有0~999999999(10億個)元素陣列下標表示數值,節點中用0表示這個數 沒有,1表示有這個數,判斷0或1只用乙個bit儲存就夠了

宣告乙個可以包含9位整數的bit陣列(10億),一共需要10億/8=120m記憶體,把記憶體中的資料全部初始化 為0 ,讀取檔案中的資料,並將資料放入記憶體。比如讀到乙個資料為341245909這個資料,那就先在記憶體中找到341245909這個bit,並將bit值 置為1 ,遍歷整個bit陣列,將bit為1的陣列下標存入檔案

關鍵**檢查是某乙個char裡面(first)的第second位中儲存的資料是否為1

bool comparebit (unsigned char first, int second)

;if (second > 8) return false;

return (first & mark_buf[second]) == mark_buf[second];

}將某乙個char(desc)中的第source位置為1

bool writetobit (unsigned char *desc, int source)

;if (source > 8) return false;

desc[0] |= mark_buf[source];

return true;

}案例在某個專案中,我們需要對2億條手機號碼刪除重覆記錄(過濾號碼黑名單同樣有效)

工作難點就在於如何處理這2億條**號碼,直接用雜湊表存放手機號碼不大現實,即使經過優化,用乙個unsigned int存放一條記錄,那也得需要2億*4=8億byte,遠超過32位系統的定址能力

解決方案:將**號碼由12位單個數字組成的字串轉換為乙個unsigned int型資料(這個完全可能,手機號碼由前三位數字和後面八位數字組成,後面八位需要佔到1~1000萬的空間,而前面用0~100的數字儲存已經足夠) ,為簡單起見,預設為0~4g的數字都有可能分布號碼,為此我們分配4g/32=512m的記憶體,將這2億個號碼整理成unsigned int型別後按上述辦法存放在這塊記憶體中(比如13512345678我們整理後為112345678,我們找到記憶體中112345678bit的下標, 並將此bit值設為1) ,遍歷整個bit陣列,記錄下所有的號碼,這些號碼即是不重複的手機號碼

總結 建立乙個足夠大的bit陣列當作hash表,以bit陣列的下標來表示乙個整數,以bit位中的0或1來表示這個整數是否在這個陣列中存在,適用於無重複 原始資料的搜尋,原來每個整數需要4byte空間變為1bit,空間壓縮率為32倍,擴充套件後可實現其他型別(包括重複資料)的搜尋

注意 由於作業系統和程式語言本身的限制,有可能記憶體足夠,但無法分配一塊連續大記憶體的情況,這樣的話可以申請多塊稍微小一點的記憶體,然後用鍊錶或其他的方式連線起來使用

發現這個思想用來排重比較好,是乙個不錯的想法.

大資料排序問題

程式描述 1 海量資料,記憶體不足,需要將檔案分割成多個檔案,從磁碟讀入 2 將每個小檔案排好序 3 歸併每個排好序的檔案,合成乙個檔案。include include qsort include include include using namespace std int sort num 10...

大資料排序問題

問題1 從100億個資料中找出前100個資料 分析 由於只要找出前100個資料,可以採用堆來進行處理。堆特別適合的場景是從海量資料中找出前m個最大值或最小值,當m不大的時候效率很高。步驟 1.讀取前100個資料,建立最小堆 最小堆的作用是方便找出目前最大的100個資料中的最小值,把待比較的資料與這個...

大資料排序

大資料開發工程師的一道經典面試題 如果待排序資料具有某些特點,往往能夠有更加有效的方法解決。同時,這種思想也更加貼近大資料應用的思維方式。對於大資料問題,分而治之的思想十分普遍。同時分布式計算 平行計算等也都類似。包括hadoop採用的map reduce模型,分而治之的思想都貫穿其中。以時間為基準...