讀《程式設計珠璣》 (一)

2022-08-31 10:39:11 字數 2309 閱讀 4615

第一章 開篇

程式設計中需求的明確化非常重要,開篇兩人的對話對此進行了說明

a:我該如何對磁碟檔案進行排序?

b:需要排序的內容是什麼?檔案中有多少條記錄?每個記錄的格式是什麼?

a:該檔案包含至多10,

000,000個記錄,每條記錄都是乙個7位整數。

b:如果檔案那麼小,為什麼要使用磁碟排序呢?為什麼不在主存中對它排序?

a:該功能是某大型系統中的一部分,大概只能提供1mb主存給它。

b:你能將記錄方面的內容說得更詳細一些嗎?

a:每個記錄是乙個7位正整數,沒有其它的關聯資料,每個整數至多只能出現一次。

..

之後我們獲得了明晰的需求

輸入:

所輸入的是乙個檔案,至多包含n個正整數,每個正整數都要小於n,這裡n=10^7

。如果輸入時某乙個整數出現了兩次,就會產生乙個致命的錯誤。

這些整數與其它任何資料都不關聯。

輸出:以增序形式輸出經過排序的整數列表。

約束:大概有1mb的可用主存,但可用磁碟空間充足。執行時間至多允許幾分鐘,

10秒鐘是最適宜的執行時間。

在有限的條件下,我們有多種的解決方案,最直接的,由於記憶體只能容納一小部分資料,因此將資料分為40份,每次讀取乙份進行快速排序,寫入中間檔案中,最後進行統一的歸併可以獲得需要的結果。然而多次的讀寫檔案操作將為大大降低程式的效率,需要更為優越的辦法。

點陣圖在實際運用中十分常見,我們可以用10000000位的字串來表示這個資料集,對於有的資料就在相應的位上置1,反之則置0。從而我們的演算法可以簡化成以下3個步驟:第一,初始化所有的位為0;第二,讀取檔案中每個整數, 如果該整數對應的位已經為1,說明前面已經出現過這個整數,丟擲異常,退出程式 (輸入要求每個整數都只能出現一次)。否則,將相應的位置1;第三, 檢查每個位,如果某個位是1,就寫出相應的整數,從而建立已排序的輸出檔案。

例項中,問題的定義佔據了非常重要的地位,明晰的定義將有助於針對性的解決問題,同時巧妙的資料結構表達將極大的節省**量和時間成本。

第二章 啊哈 演算法

第一章介紹了如何定義乙個程式設計問題,第二章則介紹下一步,即如何利用原語來解決問題,其中主要就3個演算法問題進行展開。

問題一:給定乙個包含32位整數的順序檔案,它至多只能包含40億個這樣的整數, 並且整數的次序是隨機的。請查詢乙個此檔案中不存在的32位整數。 在有足夠主存的情況下,你會如何解決這個問題? 如果你可以使用若干外部臨時檔案,但可用主存卻只有上百位元組, 你會如何解決這個問題?

如果在記憶體無限的情況下,我們可以使用第一章中的點陣圖技術進行求解。同時問題還提出如果記憶體只有上百位元組,在若干外部臨時檔案的幫助下的情況。如此可以利用二分法的思想,因為二進位制中每一位要麼是0要麼是1,對這40億數來說,進行如下操作:從最高位到最低位,對於最高位為1的分在一組,最高位為0的分在另一組,這樣40億資料就被分配成了兩組了,若兩組數有相同的個數,那麼我們可以判斷這兩組數中都缺少了全體數(2^32個)中的某乙個或者多個數,可以任選一組再次進行二分法。若兩組數目不同,我們可以肯定是小的那部分資料肯定缺少了某乙個或者多個數。因此對小的那組進行二分法,最終就能找到缺少的數。

問題二:請將乙個具有n個元素的一維向量向左旋轉i個位置。例如,假設n=8,i=3, 那麼向量abcdefgh旋轉之後得到向量defghabc。

該問題有多種的解法。一是借助中間量t,將x[0]的數放入t中,將x[0]置為x[i],x[i]置為x[2i]並直到x[0]的元素結束這次移動,之後開始移動x[1]並以此類推直到完全移動完成。

另一種方法是利用三次的反轉達到目的,顯得更為巧妙

reverse(0, i-1); // cbadefgh

reverse(i, n-1); // cbahgfed

reverse(0, n-1); // defghabc

問題三:給定一本英語單詞詞典,請找出所有的變位詞集。例如,因為「pots」, 「stop」,「tops」相互之間都是由另乙個詞的各個字母改變序列而構成的, 因此這些詞相互之間就是變位詞。

這裡需要用到一種簽名的概念,因為對某乙個單詞中字母打亂並一一匹配其它單詞的程式需要的時間令人難以置信,因此我們需要從另乙個角度來考慮問題。首先將每個單詞按字母表順序進行排序,比如「deposit」和「deiopst」的簽名都是「deiopst」,接著將簽名進行排序,可以將具有相同簽名的單詞排到一起,最終將這些具有相同簽名的單詞輸出就可以得到需要的變位詞集了。

讀《程式設計珠璣》筆記

程式設計珠璣 是一本很好的,經典的程式設計書。這兩天開始讀,有種 相見恨晚 的感覺。書中通過講述作者自己的親身體會來說明程式設計的藝術。很有感染力。第一章講述了乙個 號碼排序的故事。強調化蘩為簡的重要性。很多問題,咋一看挺難的,如果仔細分析轉化,可能會發現其實很簡單。第二章二分搜尋和排序在實際問題處...

《程式設計珠璣》筆記一

在別人不會問問題時,引導他去問問題也是乙個很大的學問,jon與乙個程式設計師問的問題而展開。如何將1千萬條記錄排序?都是七位的 號碼 最好是將時間控制在十秒鐘左右,如果不行,幾分鐘也可以,但是不能超過十分鐘,同時不可超過一兆的記憶體。jon先生要求我思考一分鐘,並給他乙個答案。我的答案有兩個,一是使...

程式設計珠璣 續(程式設計珠璣 修訂版)

經久不衰的電腦科學名著 集深邃思想 實戰技術與趣味軼事於一冊 領略電腦科學之美 程式設計珠璣 續 作譯者介紹 譯者 錢麗豔 劉田叢書名 圖靈程式設計叢書 出版社 人民郵電出版社 isbn 9787115251510出版日期 2011 年5月 程式設計珠璣 續 是電腦科學方面的經典名著 程式設計珠璣 ...