超大文件排序


如何編譯測試文件生成程序和排序程序

c++,Vs2013下開發,win10 64。
2015/10/30

如何生成測試文件

1、隨機生成一個字符串

即: 隨機生成一個長度n的字符串;

  • 思想
    新建一個空的字符串,然后每次在字符表的字典中隨機取一個元素,添加到字符串中,重復n次;

但是效率比較低。

  • 改進:

    • 若內存允許,將字符表中的單個元素兩兩組合,得到一個元素長度為2的字符串集合的候選列表
    • 同理,由字符表元素長度為2的字符串集合的候選列表可以得到元素長度為3的字符串集合的候選列表....以此類推。
    • 將包含單個字符的字符表元素長度為2的字符串集合的候選列表元素長度為3的字符串集合的候選列表放到一個表里面,得到最終的候選字符串列表
  • 算法:

    1. 新建一個空的字符串
    2. 每次從候選字符串列表中隨機選擇一個字符串,添加到字符串中,重復n次。
    3. 將字符串存到文件中,重復足夠多次,得到隨機文件。

如何執行排序程序

  • 算法步驟(兩步):
  1. 對每一個大文件進行排序,
  2. 對這幾個排序好了的大文件多路歸並合並到一個文件中。
  • 步驟1
    這里借用快速排序(分治)的思想,將文件分成足夠小的小文件,並用一個樹結構保存生成的文件名。

    step1,將選取文件第一個字符串作為標准字符串,將文件分成兩個較小的文件;
    step2,第一個文件中所有的字符串比標准字符串小或等於,第二個文件中所有的字符串比標准字符串大;
    step3,判斷生成的文件的大小,若足夠小,則對其中的數據全部讀入內存,排序;若還是比較大,則對該文件繼續執行step1
    step4 合並。每個足夠小的文件中的內容都排序后,根據紀錄分解過程的樹的最外圍的子葉節點所記錄的文件進行合並(已知前一個文件中所有的元素比后面文件中的小,只要把后一個文件追加到前一個就可以)。生成一個已經拍好序的大文件。
    step5 根據據紀錄分解過程的樹,刪除分解過程中生成的臨時文件。

如圖,每個節點代表一個文件,節點的左子節點的文件中的所有的字符串 比 右子節點的文件中的所有的字符串 小。
將所有最外圍的葉節點依次排序,就能得到排好序的大文件。

結果示例。

  • 步驟2
    借用歸並排序中歸並的方法(多路歸並).
    1. 對每個已經排好序的大文件,讀取其第一個元素,放到內存中,按順序組成一個列表;
      取列表中最小的元素作為追加到 輸出文件中。
    2. 再從最小元素所在的文件中讀取一個元素,放到列表的相應位置。
    3. 如此反復,知道所有文件被讀完。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM