資料分割排序的實現

2021-08-13 17:55:26 字數 2859 閱讀 5611

6196302

3557681

6121580

2039345

2095006

1746773

7934312

2016371

7123302

8790171

2966901

...7005375

現在要對這個檔案進行排序,怎麼搞?(題目位址

文章給出的一種解決方式就是,先把大檔案分割成若干小檔案,然後把小檔案的資料進行排序,然後把資料歸併合成最後的結果,歸併的原理就是比較幾個小檔案中的最小值。min=min(min(s1),min(s3),min(s3),...),這也是比較經典的一道面試題。下面我們來實現一下。

第一步,先製造一些資料,由於是本地電腦,我先少量的製造一些資料,只造了一萬條資料

private static void createdata(string filename, int linenum) 

}// 批處理餘下的

if(sb.length() > 0)

system.out.println("**********===製造資料*****結束**********==");

}

第二步開始分割這些資料,每一千條切割到乙個小檔案中儲存

// 將大檔案進行切割,分成一些小的檔案

private static listpartdata(string filename, int size)

}// 處理餘量

if(sb.length() > 0)

} catch (ioexception e) finally catch (ioexception e) }}

system.out.println("*****===分割小檔案====結束*****=");

return partfilenamelist;

}

第三步,把這些小檔案做內部排序,然後儲存為新的檔案,資料量不大,使用氣泡排序

private static string sortpartfiledata(string partfile) 

}// 放入list,對list進行排序

list = sortutils.bubblesort(list);

// 排序後的結果寫入新的檔案,返回新檔名

sortedfilename = partfile.replace("aa_part_", "aa_part_sorted_");

stringbuilder sb = new stringbuilder();

for (integer num : list)

// 寫入新檔案

fileutils.write2file(sortedfilename, sb.tostring());

} catch (ioexception e) finally catch (ioexception e) }}

system.out.println("*****=單個小檔案排序*****=結束**********");

return sortedfilename;

}

第三步,把結果歸併,每次取各個子檔案的最小值,其中有個比較糾結的地方,我是把所有子檔案都讀到記憶體中的,這樣還是相當於把整個大檔案讀入記憶體,如果檔案非常大的話,就需要大記憶體,但是如果不把所有資料一次讀入記憶體的話,每比較一次最小值都要重複讀取一次子檔案,這個io的消耗會更加的大,這個地方我也沒有想到更好的解決方案。

// 取每個子檔案的最小值,然後排序

private static string sortdatafromsortedpartfile(listsortedpartfilelist)

// 權衡io開關消耗和記憶體消耗,確定方案,是每次開啟讀寫還是子檔案內容儲存在記憶體中

// 此處demo的資料量不大,為了簡便我就都讀進來了

map> partdata = new hashmap>();

// 目前資料不是很大,先把資料讀出來

for (string fn : sortedpartfilelist)

stringbuilder sb = new stringbuilder();

int counter = 0;

int batchsize = 10000;

// 權衡io開關消耗和記憶體消耗,確定方案,是每次開啟讀寫還是子檔案內容儲存在記憶體中

while(true)

// 如果連不到值, -1代表子檔案沒有資料了

listdatalist = partdata.get(fn);

if (index >= datalist.size())

string datastr = datalist.get(index);

int data = numberutils.toint(datastr, min);

if(data < min)

}if (ispartfiledataover(minindex))

system.out.println("**********=排序結束**********=");

break;

}system.out.println(usefn+"*****==min**********"+min);

// 迴圈結束得到最小的乙個值

// 記錄每個子部分取值的指標

minindex.put(usefn,minindex.get(usefn)+1);

counter++;

if(counter % batchsize == 0)

}return resultfilename;

}

實際快速排序 分割策略

快速排序,樞紐元 比較值 理論上選哪個都可以。實際快速排序包括劃分策略 和遞迴呼叫。public static super anytype void quicksort anytype a private static final int cutoff 3 public static void sw...

Linux檔案分割,sql排序

split命令可以將乙個大檔案分割成很多個小檔案,有時需要將檔案分割成更小的片段,比如為提高可讀性,生成日誌等。b 值為每一輸出檔案的大小,單位為 byte。c 每一輸出檔案中,單行的最大 byte 數。d 使用數字作為字尾。l 值為每一輸出檔案的列數大小。例 將大檔案分割為10k大小的檔案,名字字...

資料的水平分割

早前公司有個大系統沒有做資料的水平分割,導致興許的效能優化不能做到最佳,有些功能優化到7s,8s就無法繼續了。這個大系統曾經是分21個點部署,然後進行了大集中,僅僅部署了乙個點。1.在做資料的水平切割之前一定要理解系統的業務。我的系統是mis,資料能夠分為兩類 一類是基礎資料,一類是業務流程資料。基...