1. 程式人生 > >上億個資料儲存在硬碟中,找出最大的N個。

上億個資料儲存在硬碟中,找出最大的N個。

(1)先選N個元素組成一個小根堆,然後遍歷剩下的資料,如果第i個元素M大於小根堆的根結點,就刪除這個根結點,並將元素M插入這個小根椎,最後,小根堆中的元素就是最大的N個元素。

(2)只要開闢一個稍微大一點的緩衝區存放大於某選定值的資料即可,當緩衝滿時,重新整理選定值為緩衝區的第n大值,即可(同時清理快取區)。

(3)用O(M)的時間找出第N大元素,然後再遍歷一邊找出比這個數大的N個數即可,理論複雜度O(M),不過N較小的時候可能是1L的更有效率

解法(1)及時考慮資料不可能全部加入記憶體,也可以在記憶體中開闢一個緩衝區,每次讀取磁碟中的K(K<M)個數據進入記憶體,然後在一個一個的與堆進行比較。當緩衝區空時,則再讀入K個數據。總之減少IO讀取次數也是一個高效的重要方面。

解法(2)如何選定值

解法(3)是一個方向,可以使用快速排序演算法,選擇遞迴搜尋的方向,理論上可以達到O(M),但找第N大元素時,如何不需要把所有資料讀入記憶體呢?

給出方法(1)的一個演算法,使用set,有重複資料也可以用multiset,set使用的是紅黑樹,可以改善插入、刪除的效率

int main(int argc, char* argv[])
{
	set<int> set_MAX_N;
	ifstream inFile("test.txt");
	int nTemp;
	while(inFile >>nTemp)
	{
		set_MAX_N.insert(nTemp);
		if(set_MAX_N.size() > N)
		{
			set_MAX_N.erase(set_MAX_N.begin());
		}
	}
	for(set<int>::iterator it = set_MAX_N.begin();it != set_MAX_N.end(); it ++)
		cout<< *it <<endl;
	while(1);
	return 0;
}

相關推薦

資料儲存硬碟N

(1)先選N個元素組成一個小根堆,然後遍歷剩下的資料,如果第i個元素M大於小根堆的根結點,就刪除這個根結點,並將元素M插入這個小根椎,最後,小根堆中的元素就是最大的N個元素。 (2)只要開闢一個稍微大一點的緩衝區存放大於某選定值的資料即可,當緩衝滿時,重新整理選定值為緩衝區

在由N正整數的集合S元素C滿足C=A + B

其中A,B都是集合S中元素,請給出演算法描述,程式碼與時間複雜度分析. int findNum(vector<int> &S) { sort(S.begin(), S.end()); int n = S.size(); for (

資料結構與演算法——有1整數的1000要求時間越短越好空間佔用越少越好

有1億個整數,找出最大的1000個,要求時間越短越好,空間佔用越少越好(迅雷筆試) 首先要明白1億個整數佔用多大的記憶體,按每個整數4個位元組來算,用400000000B,大約400000KB,大約4

程式學習資源介紹適合你的入門課程

身處在這個「全民學程式」時代,幾年後當程式設計變成連國中生都必備的能力時,不會寫程式的人在未來就要變成少數民族。越來越多人開始想要學程式,但網路到底哪裡有資源可以幫助我們學習?每種學習資源都有不同的特色,又有哪些是比較適合我的呢?在這篇文章中,我們將認識七個各有不同適合族群的學習資源與線上網站。為了避免新手在

設計一個演算法從數 A[1:n] 同時元素和小元素只需要不超過 1.5n-2 次比較

題目:設計一個演算法從數A[1:n]中同時找出最大元素和最小元素,只需要不超過1.5n-2次比較。 #include <stdio.h> #define MIN -1 #define MAX 65535 void find_max_min( int num[], int len ) {

設計一個算法從數 A[1:n] 同時元素和小元素只需要不超過 1.5n-2 次比較

number com str png 統計 最小 int 比較 技術分享 題目:設計一個算法從數A[1:n]中同時找出最大元素和最小元素,只需要不超過1.5n-2次比較。 #include <stdio.h> #define MIN -1 #define MAX

小菜鳥請求各位大大幫忙在一個字元陣列長連續重複的字元子序列

各位大俠你好,題目的意思如下。 請輸入一個字元陣列,在字元陣列中找出最長的連續相同字元的子序列。 比如 fabcddFFFg中相同字元子序列有 dd和FFF,那麼最長的就是FFF.我下的程式碼如下,通過鍵盤輸入一系列字元,然後讀取到陣列中。 import java.util

再來練一遍模擬鍵盤輸入數字值和小值

package yn.ngems.cn.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class InputUtil {  

模擬輸入數字值和小值

package yn.ngems.cn.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader

典型的Top K演算法 _找出一個數組裡面前K個最大數_找出1億個浮點數中最大的10000_一個文字檔案,找出前10經常出現的詞但這次檔案比較長說是上億行或十總之無法一次讀入記憶體.

        搜尋引擎會通過日誌檔案把使用者每次檢索使用的所有檢索串都記錄下來,每個查詢串的長度為1-255位元組。         假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。一個查詢串的重複度越高,說明查詢

java兩list儲存bean物件其中某一屬性不同的元素

在java中運用List集合儲存物件,如果想找到兩個list中不同的部分,可以用ArrayList的contains方法,遍歷每一個物件,判斷是否是相等的,如下: public stati

n字符m排列組合

scan maxlength else include sizeof 排列組合 length char col 網上看到的版本 #include <string.h> #include <stdio.h> #include <stdlib.h

100數字的10

1、首先一點,對於海量資料處理,思路基本上是:必須分塊處理,然後再合併起來。 2、對於每一塊必須找出10個最大的數,因為第一塊中10個最大數中的最小的,可能比第二塊中10最大數中的最大的還要大。 3、分塊處理,再合併。也就是Google MapReduce 的基本思想。Google有很多的伺服器,每個伺服器

海量資料出現次數TOPK的記錄

題目:在一個文字中有大量的字串記錄,統計出現次數最多的字串及其次數。 思路:使用STL中的map可以快速的解決這個問題,map是一類關聯式容器,通過RB樹實現的,自動建立key-value的對應,key和value可以是任何型別。 #include <iostrea

TOP-K排序演算法從海量不重複資料/小的K個數

如題,TOP-K排序的主要功能是找出一堆不重複資料中的最小或最大的幾個數,此處我們介紹這種型別題目的某種解法: 最大最小堆,最大堆結構裡面的每一個數不都是小於root的值麼?和我們要解決的問題很像。由此,我們可以構造一個堆,並且用它來儲存我們需要找的那幾個數。有這麼一個動態

用c# 採用BIT-map 方式從一堆資料不重複的

採用的是bit-map演算法,關於什麼是bit-map,百度一下; 直接上一段程式碼,用C#改寫的! 如下:  class Program     {         private static int[] flags = new int[1000000];    

演算法-十數字的一萬--9-3

十億的資料量    4G記憶體空間 1.建陣列  迴圈一萬次 找出最大的一萬個   複雜度o(n*m) n為10億  m為1萬 2.藉助快速排序    複雜度o(nlogn) 3.不想放入記憶體 佔據如此大的空間 建一個長度為1萬的陣列    將前1萬個數字放入陣列   其

100資料的1000數字(top K問題)

在大規模資料處理中,經常會遇到的一類問題:在海量資料中找出出現頻率最好的前k個數,或者從海量資料中找出最大的前k個數,這類問題通常

無序數組的兩(K)數

數組;查找;最大;K個**給你一個整型數組,我想找出來最大的兩個數,能幫我寫一個算法嗎? **在上一遍我們已經解讀過這道題目了,包括我們能想到的問題。這裏我們按照解決算法題的一般步驟再來一起分析一下這道題: 一、確保我們理解了問題,並且嘗試一個例子,確認理解無誤。 那現在我們澄清一下問題,我們需要從這樣的數

在一個無序整數數組連續增長片段長的一段, 增長步長是1Example: [3,2,4,5,6,1,9], 長的是[4,5,6]

lse [] 是我 == push color 感覺 bsp emp 在一個無序整數數組中,找出連續增長片段最長的一段, 增長步長是1。Example: [3,2,4,5,6,1,9], 最長的是[4,5,6] 下面是我自己的編寫的代碼,感覺還能再優化。 希望有大神可以分享