日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

大数据算法:对5亿数据进行排序

發布時間:2025/3/20 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大数据算法:对5亿数据进行排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0.前言:

在大數據研究的路上,我們總要對一些很大的數據進行各種各樣的操作。比如說對數據排序,比如說對數據統計,比如說對數據計算。而在大量的數據面前,我們總是束手無策,因為我們無法在限定時間的情況下,在效率上做到讓人滿意,也無法在限定空間的情況下,能夠快速解決問題。可能我們在一些日常的開發過程中,沒有遇到過這些問題。不過,現在是時候來考慮一下這樣的問題了。因為,現在正值大數據的時代。

在本文中我會用三種方法,從兩個方面來說明如何解決對5億數據進行排序工作。

1.版本說明

商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
本文作者:Q-WHai
發表日期: 2015年10月24日
本文鏈接:https://blog.csdn.net/lemon_tree12138/article/details/48783535
來源:CSDN
更多內容:分類 >> 算法與數學

2.思路分析:

? 拿到這樣的一個問題,你的第一感覺是什么?冒泡排序?選擇排序?插入排序?堆排?還是快排?可能你的想法是我的內存不夠。的確,這么大的一個數據量,我們的內存的確不夠。因為單是5億的整數數據就有3.7個G(別說你是壕,內存大著呢)。既然內存不夠,那么我們要怎么來解決呢?

? 要知道我們一步做不了的事,兩步總能做到。那么我們就來嘗試第一步做一些,剩下的一些就等會再來搞定吧?;谶@樣的思路,就有下面的一個解題方法——分治!

1.分治——根據數據存在文件中的位置分裂文件到批量小文件中

? 相對于樸素的排序,這是一種比較穩妥的解決方法。因為數據量太大了!我們不得不將大事化小,小事化了。

? 這里我們的做法是每次讀取待排序文件的10000個數據,把這10000個數據進行快速排序,再寫到一個小文件bigdata.part.i.sorted中。這樣我們就得到了50000個已排序好的小文件了。

? 在有已排序小文件的基礎上,我只要每次拿到這些文件中當前位置的最小值就OK了。再把這些值依次寫入bigdata.sorted中。

2.分治——根據數據自身大小分裂文件到批量小文件中

? 按照數據位置進行分裂大文件也可以。不過這樣就導致了一個問題,在把小文件合并成大文件的時候并不那么高效。那么,這里我們就有了另一種思路:我們先把文件中的數據按照大小把到不同的文件中。再對這些不同的文件進行排序。這樣我們可以直接按文件的字典序輸出即可。

3.字典樹

? 關于字典樹的基本使用,大家可以參見本人的另一篇博客:《數據結構:字典樹的基本使用》

? 基于《數據結構:字典樹的基本使用》這篇博客中對字典序的講解,我們知道我們要做就是對字典樹進行廣度優先搜索。

?

3.結構設計圖:

??

?

4.代碼分析:

0.分治

(0)分割大文件

? 此步對大文件的分割是按序進行的,這樣我們就可以確保數據的離散化,不會讓一個小文件中的數據很多,一個小文件的數據很少。

?

public static void splitBigFile2PartBySerial(String filePath, String partPath) throws IOException {File file = new File(filePath);FileInputStream inputStream = new FileInputStream(file);BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuffer buffer = new StringBuffer();String readerLine = "";int line = 0;while ((readerLine = reader.readLine()) != null) {buffer.append(readerLine + " ");if (++line % Config.PART_NUMBER_COUNT == 0) {sortStringBuffer(buffer);int splitLine = line / Config.PART_NUMBER_COUNT;write(partPath.replace("xxx", "" + splitLine), buffer.toString());buffer.setLength(0);System.out.println("SPLIT: " + splitLine);}}reader.close();}

?

(1)排序

?

? 即使是已經切割成小份的了,不過每個小文件中的數據集仍然有50000個。因為50000個數據也不是一個小數據,在排序的過程中,也會有一些講究,所有這里我們使用的是快排。如下:

?

public static void sortStringBuffer(StringBuffer buffer) {String[] numberTexts = buffer.toString().split(" ");buffer.setLength(0);int[] numbers = new int[numberTexts.length];for (int i = 0; i < numberTexts.length; i++) {numbers[i] = Integer.parseInt(numberTexts[i]);}int[] sorted = QKSort.quickSort(numbers);for (int i = 0; i < sorted.length; i++) {buffer.append(sorted[i] + "\n");}}

?

(2)合并

?

? 在合并的時候,我們要明確一個問題。雖然我們的單個小文件已經有序,不過我們還并不知道整體的順序。比如:

? 文件1:1 2 4 6 9 34 288

? 文件2:4 5 6 87 99 104 135

? 上面的兩個文件雖然每個文件內部已經有序,不過整體來說,是無序的。對于在單個文件有序的基礎上,我們可以做一些事情。我們可以把每個文件中的數據看成是一個隊列,我們總是從隊列的首部開始進行出隊(因為隊列的頭部總是最小的數)。這樣,我們就把問題轉化成從N個小文件中依次比較,得到最小的結果并記入文件(當然,我們不可以生成一個數就寫一次文件,這樣太低效了,我們可以使用一個變量緩存這此"最小值",在累計到一定數量之后再一次性寫入。再清空變量,循環反復,直到文件全部寫入完畢)。

?

public static void mergeSorted(String dirPath) throws NumberFormatException, IOException {long t = System.currentTimeMillis();File dirFile = new File(dirPath);File[] partFiles = dirFile.listFiles();FileInputStream[] inputStreams = new FileInputStream[partFiles.length];BufferedReader[] readers = new BufferedReader[partFiles.length];int[] minNumbers = new int[partFiles.length];for (int i = 0; i < partFiles.length; i++) {inputStreams[i] = new FileInputStream(partFiles[i]);readers[i] = new BufferedReader(new InputStreamReader(inputStreams[i]));minNumbers[i] = Integer.parseInt(readers[i].readLine());}int numberCount = Config.TOTAL_NUMBER_COUNT;while (true) {int index = Tools.minNumberIndex(minNumbers);System.out.println(minNumbers[index]);write(Config.BIGDATA_NUMBER_FILEPATH_SORTED, minNumbers[index] + "\n");minNumbers[index] = Integer.parseInt(readers[index].readLine());if (numberCount-- <= 0) {break;}}System.err.println("TIME: " + (System.currentTimeMillis() - t));for (int i = 0; i < partFiles.length; i++) {inputStreams[i].close();readers[i].close();}}

注:這里關于分治的算法,我就只提供一種實現過程了??赡軓纳厦娴恼f明中,大家也意識到了一個問題,如果我們把大文件中的數據按照數值大小化分到不同的小文件中。這樣會有一個很致命的問題,那就是可能我們的小文件會出現兩極分化的局面,即有一部分文件中的數據很少,有一部分小文件中的數據很多。所以,這里我就不再提供實現過程,在上面有所說明,只是想說我們在解決問題的時候,可能會有很多不同的想法,這些想法都很好,只是有時我們需要一個最優的來提升逼格(^_^)。

?

1.字典樹

? 因為我們知道字典樹是可以壓縮數據量的一種數據結構,尤其是針對那么使用的字符串個數有限(比如:'0','1','2','3','4','5','6','7','8','9'),并整體數量很多的情況。因為我們可以可以讓同一個字符重復使用多次。比如:"123456789"和"123456780"其實只使用了'0'-'9'這10個字符而已。關于字典樹的實現,我想是很簡單的一種方法。如果你還是感覺有些朦朧和模糊的話,就請參見本人的另一篇博客《數據結構:字典樹的基本使用》,在那一篇博客中,我有很詳細地介紹對字典樹的各種基本操作及說明。

? 這里我還是貼出一部分關鍵的代碼,和大家一起學習吧。代碼如下:

(0)將數據記入文件

?

public static void sortTrie(String filePath) throws IOException {File file = new File(filePath);FileInputStream inputStream = new FileInputStream(file);BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));TrieTree tree = new TrieTree("sorting");String readerLine = "";int line = 0;while ((readerLine = reader.readLine()) != null) {tree.insert(readerLine);if (++line % Config.PART_NUMBER_COUNT == 0) {System.out.println("LINE: " + line);}}System.out.println("文件讀取完畢");writeTrieTree2File(Config.BIGDATA_NUMBER_FILEPATH_SORTED, tree);reader.close();}

?

(1)對字典樹進行廣度優先搜索

?

?

public static void sortNumberOrder(String filePath, Node node) throws IOException {Queue<Node> queuing = new LinkedList<Node>();queuing.offer(node);while (!queuing.isEmpty()) {Node currentNode = queuing.poll();if (currentNode.isEnd()) {buffer.append(getNodePath(currentNode) + "\n");if (++index % 50000 == 0) {write(filePath, buffer.toString());}}Node[] children = currentNode.getChildren();for (Node sonNode : children) {if (sonNode != null) {queuing.offer(sonNode);}}}}/*** 獲得某一節點的上層節點,即前綴字符串* @param node* @return*/public static String getNodePath(Node node) {StringBuffer path = new StringBuffer();Node currentNode = node;while (currentNode.getParent() != null) {path.append(currentNode.getName());currentNode = currentNode.getParent();}return path.reverse().toString();}

?

5.小結:

?

在大數據的探索還遠不止于此。還有很多東西等著我們去了解,去發現,以及創造。

而對于大量數據的問題,我們可以利用分治來化解它的大,從而可以更方便地去觀察全局。也可以使用我們已經學習過的一些數據結構及算法來求解問題。不過隨著我們不斷地學習,不斷地探索,我們可能會感覺到自己學習的一些固有的數據結構和算法并不能完全地解決我們遇到的問題,那么就需要我們的創造力了。

總結

以上是生活随笔為你收集整理的大数据算法:对5亿数据进行排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲精品18 | 中文字幕久久久久 | 国产精品久久久久久久久久小说 | 国产免费黄色小视频 | 精品啪啪 | 久久精品国产99久久不卡 | 久久久久久久中文字幕 | 国产午夜精品理论片在线 | 欧美日本日韩 | 国产在线视频第一页 | 国产av天堂无码一区二区三区 | 999国产精品亚洲77777 | 在线观看av一区 | 熊猫成人网 | 久久538 | 深田咏美av在线 | 大学生三级中国dvd 日韩欧美一区二区区 | 舒淇裸体午夜理伦 | 欧洲黄色录像 | 男男全肉变态重口高h | 亚洲欧美日韩久久 | 国产精品精品国产 | 日韩系列在线 | 日本内谢少妇xxxxx少交 | 亚洲精品视频免费观看 | 欧美日韩在线视频免费 | 欧美日韩不卡 | 老司机深夜福利视频 | 欧美三级少妇高潮 | 亚洲精品码 | 成人精品一区二区 | 国产69久久精品成人看 | 悠悠色在线| 日韩亚洲在线 | 欧美综合网站 | 性色av一区二区三区红粉影视 | 丁香花国语版普通话 | 狠狠伊人 | 日本大尺度床戏揉捏胸 | 国产精品中文 | 国产乱淫av片 | 熟女人妻在线视频 | 6080福利 | 奇米影视在线视频 | 国产国语亲子伦亲子 | 成年人在线播放视频 | 狠狠久久久 | av在线中文 | 成人网在线免费观看 | 欧美综合在线视频 | 国产尤物av| 国产白丝一区二区三区 | 国产九九热 | 国产午夜一级一片免费播放 | 欣赏asian国模裸体pics | 久久久无码精品亚洲无少妇 | 亚洲区免费| 琪琪色在线视频 | 三级黄色在线视频 | 99国产精品自拍 | 无码人妻丰满熟妇区毛片18 | 柠檬av导航| 青青草精品 | 色99999| 韩国午夜激情 | 中文字幕18页 | 天天艹天天爽 | 欧美激情一区二区三区免费观看 | 亚洲三级免费 | 国产乱人乱偷精品视频a人人澡 | 91传媒理伦片在线观看 | 色欲色香天天天综合网www | 亚洲在线播放 | 在线观看成年人网站 | 天堂√在线| 亚洲综合一 | 九色蝌蚪porny | 精品人妻无码一区二区三区蜜桃一 | 国产97视频 | 国产一区二区三区四区五区美女 | 制服丝袜国产精品 | 国产日韩在线看 | 另类专区成人 | 日本老熟妇乱 | 五月婷婷视频在线观看 | 香蕉视频色 | 日本孰妇毛茸茸xxxx | 奇米久久久 | av桃色| 91免费精品 | 九九热免费精品视频 | 成人av一区二区三区在线观看 | 天天艹av | 清冷男神被c的合不拢腿男男 | 韩国国产在线 | 美女破处视频 | 欧美大肥婆大肥bbbbb | 又大又粗弄得我出好多水 | 丰满少妇一区二区三区视频 |