我正在尝试在一个二进制文件上执行外部插入排序,该二进制文件充满0到1之间的随机双精度。我在“value”和“temp”分配之后添加了一堆println语句,看起来他们正在获取每次迭代都是相同的值。我认为我没有正确遍历文件。
public class ExternalFileSort
{
public static void sort(String filename, int length) throws IOException
{
int i, j;
double value, temp;
RandomAccessFile file = new RandomAccessFile(filename, "rw");
for (i = 1; i < length; i++)
{
file.seek(i);
temp = file.readDouble();
j = i-1;
file.seek(j);
value = file.readDouble();
while (j >= 0 && value > temp)
{
file.seek(j+1);
file.writeDouble(value);
j--;
}
file.seek(j+1);
file.writeDouble(temp);
}
file.close();
}
}
答案 0 :(得分:0)
假设您根据该定义在文件中写入了双打(这是强制性先决条件)https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeDouble%28double%29
RandomAccessFile file = new RandomAccessFile(filename, "rw");
long currentPosition = 0L;
while (currentPosition < file.length()) {
double current = file.readDouble();
double min = current;
long minPosition = currentPosition;
// Find the smallest value in the rest of the file
while (currentPosition < file.length()) {
double candidate = file.readDouble();
if (candidate < min) {
min = candidate;
minPosition = file.getFilePointer() - 8;
}
}
// Swap
file.seek(minPosition);
file.writeDouble(current);
file.seek(currentPosition);
file.writeDouble(min);
currentPosition = file.getFilePointer();
}
未经测试,但您明白了。
答案 1 :(得分:0)
您应该知道的第一件事是double
类型使用8个字节。如果您的文件是双精度二进制数组,则前8个字节将对应于第一个双精度数,后8个字节将对应于第二个双精度数,依此类推。例如,如果在执行file.seek(1)
后尝试读取双精度数,则会读取一个混乱的值,因为它将由第一个双精度的7个字节和第二个的第一个字节组成。
首先将整个文件读入双精度数组,在数组中执行排序算法,然后将生成的数组写回磁盘,会更容易,更有效。对于第一部分,您将使用int size = file.length() / 8;
计算双打数。然后,您将创建一个具有此大小的双精度数组,并使用相应数量的file.readDouble()
调用读取它们
如果您必须直接在二进制文件上执行整个操作,请不要忘记在搜索操作中文件内部的双精度实际位置应乘以8,以便将它们转换为字节位置。例如:第一个双头位于0位置,第二个位于8位,第三个位于16位,依此类推。