程式設計珠璣 第一章解析

2021-06-07 07:56:21 字數 1499 閱讀 3105

問題:

輸入:乙個最多包含n個正整數的檔案,每個數都小於n(n=1000w)。如果在輸入檔案中有任何整數重複出現就是致命錯誤。沒有其他資料與該整數相關聯。

輸出:按公升序排列的輸入整數的列表。

約束:最多有(大約)1 mb的記憶體空間可用,有充足的磁碟儲存空間可用。執行時間最多幾分鐘,執行時間為10秒就不需要進一步優化了。

方法一:歸併排序。(耗時間)

歸併排序需把資料全部讀入記憶體,1000w個整數的大小是1000w*4/(1024*1024)大約是40m(假設乙個整數是4位元組),顯然不能將全部資料讀入記憶體。

方法二:分段排序。(耗時間)

將這些整數分成40組,分別是[0-249999]  [250000-4999999]  … [9750000-9999999],然後遍歷40次。這樣時間複雜度是40n,空間複雜度是n/40,比歸併要好點。當然也可以把範圍擴大或者縮小。

方法三:位圖法。

用1位來表示[0~n-1]中的整數是否存在。1表示存在,0表示不存在。這樣的話進行一次遍歷,就可以進行排序了,而且空間複雜度是n/(8*1024*1024)。例如對於20個數來說,如果集合是.那麼其位圖表示法如下:01110100100001000000(說明:左邊第一位表示 0 )。

程式:

利用bitset

#include

#include

#include

using namespace std;

int main()

for (i=0;i<1000000;++i)  

} return 0;}

利用位邏輯運算

事實上,我們是用每乙個元素表示乙個32位的二進位制字串這樣這個元素可以保留相鄰32個號碼是否存在的資訊,陣列範圍就下降到了10000000/32了,例如對於號碼89256,由於89256 mod 32=2789…8,這樣我們應該             置a[2789]中32位字串的第8位(從低位數起)為1現在問題的關鍵是,如何用位邏輯運算來表示這種操作。

#include

#include

#define shift 5

#define mask 0x1f

#define n 10000000

int a[1 + n/32];

// 置位函式----用「|」操作符,i & mask相當於mod操作

//m mod n 運算,當n = 2 的x次冪的時候,m mod n = m & (n-1)

void set(int i)

void clr(int i)

int  test(int i)

int main()

程式設計珠璣第一章

原文中的問題 如何在1mb的空間裡面對一千萬個整數進行排序?並且每個數都小於1千萬。實際上這個需要1.25mb的記憶體空間。1mb總共有838,8608。所以估計也可以在1mb左右的空間裡面進行排序了。include include define bitsperword 32 define shif...

程式設計珠璣第一章

下午看完程式設計珠璣第一章,感覺很不錯!如作者所說 閱讀本書乙個提示,不要太快,一次閱讀一章。集中精力思考,解答課後習題。寫總結就是在剛弄懂的時候,這時候是最恰當的時候,最容易接受。題目要求 乙個最多含有1000萬個整數的檔案,整數沒有重複,請輸出公升序排列。約束 最多1m記憶體,時間10s。題目很...

《程式設計珠璣》第一章筆記

文章從乙個實際的問題開始 乙個 系統,7位數的 號碼,用1mb的記憶體空間將這些 號碼排序。分析 如果將這些 號碼看成int型別的整數,將其讀入記憶體中進行排序,int型別4個位元組,最多有10000000個 號碼,則需要40mb的記憶體空間,遠遠超出題目的要求,但是這10000000個資料有他們的...