我写了一个类似于外部排序的程序。我从这个博客中得到了一个好主意。在这里,他们试图只做外部排序的数字。我的要求有点不同。我的输入文件可能有超过百万条记录,并且很难在内存中对它们进行排序,所以我必须利用我的磁盘。我将我的输入分成不同的部分,对其进行排序,然后将其存储在临时文件中。然后将排序后的输出合并到一个文件中。下面我可以将其拆分为临时文件,然后仅合并密钥。
我有一个输入文件如下:
key1 abc
key2 world
key1 hello
key3 tom
key7 yankie
key3 apple
key5 action
key7 jack
key4 apple
key2 xon
key1 lemon
假设磁盘上文件的大小是 10,内存缓冲区可以容纳的最大项目是 4,所以我所做的是一次获取 4 条记录并将其存储在 HashMap 中,将我的值与更新的计数一起排序。该输入将被拆分为 3 个排序文件,如下所示。您可以看到,对于每个键,我都有一个计数以及词典上的最高值。
临时文件-0.txt
key1: 2, hello
key2: 1, world
key3: 1, tom
临时文件 1.txt
key5: 1, action
key3: 1, apple
key7: 2, yankie
临时文件 2.txt
key1: 1, lemon
key2: 1, xon
key4: 1, apple
然后合并所有这 3 个文件后,输出应如下所示:
key1: 3 lemon
key2: 2 xon
key3: 2 world
key5: 1 action
key7: 2 yankie
我不确定将整行与计数和该键的字典最高值合并的逻辑,我的以下代码能够给我所有键,如下所示:
key1
key1
key2
key2
key3
key4
key5
key3
key7
在下面的代码中,我打开每个文件并合并它们,然后写回磁盘到一个名为external-sorted.txt
static int N = 10; // size of the file in disk
static int M = 4; // max items the memory buffer can hold
int slices = (int) Math.ceil((double) N/M);
String tfile = "temp-file-";
//Reading all the 3 temp files
BufferedReader[] brs = new BufferedReader[slices];
String[] topNums = new String[slices];
for(i = 0; i<slices; i++){
brs[i] = new BufferedReader(new FileReader(tfile + Integer.toString(i) + ".txt"));
String t = brs[i].readLine();
String[] kv = t.split(":");
if(t!=null){
topNums[i] = kv[0];
}
//topNums [key1, key5, key1]
}
FileWriter fw = new FileWriter("external-sorted.txt");
PrintWriter pw = new PrintWriter(fw);
for(i=0; i<N; i++){
String min = topNums[0];
System.out.println("min:"+min);
int minFile = 0;
for(j=0; j<slices; j++){
if(min.compareTo(topNums[j])>0)
{
min = topNums[j];
minFile = j;
}
}
pw.println(min);
String t = brs[minFile].readLine();
String[] kv = new String[2];
if (t != null)
kv = t.split(":");
topNums[minFile] = kv[0];
}
for (i = 0; i < slices; i++)
brs[i].close();
pw.close();
fw.close();
}
任何想法表示赞赏。请询问,如果您有任何问题。TIA。