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,資料能夠分為兩類 一類是基礎資料,一類是業務流程資料。基...