考虑到机器只有96字节的可用内存,我需要模拟外部排序算法。我使用32字节结构,如下所示:
typedef struct {
char usedmemory[31];
char key;
}Register32;
我已经在很多3个Register32二进制文件中分割了一个大的tobesorted.txt文件。例如:
I N T E R C A L A C A O B A L A N C E A D A
分为8个文件,这些文件在内部排序,范围从file0.bin到file7.bin,包含31个字节的垃圾,1个字节是用于随时对寄存器进行排序的键。
file0.bin containing INT
file1.bin containing CER
file2.bin containing AAL
file3.bin containing ACO
file4.bin containing ABL
file5.bin containing ACN
file6.bin containing ADE
file7.bin containing A
我的任务是"合并"在任何给定时间将这些文件中的2,3或4个放入退出文件中并保持合并,直到我将所有初始单词全部整理出来。示例:将file0与file1合并将输出C E I N R T. 在退出文件中。当然,合并函数应该被概括为一次读取每个排序键并且无论文件输入大小如何都合并到退出文件中。 My Merge函数接收一个文件数组,这些文件可以包含2,3或4个文件(函数不知道),提到的数组的最低索引,更高的索引和退出文件。它看起来像这样:
void MergeFunction(TypeFile* entry, int lowerindex,int higherindex, TypeFile exitfile){
int i, j, count = 0;
}
TypeFile只是typedef FILE* TypeFile;
。
我知道我应该一次比较每个寄存器的密钥,然后如果我需要模拟内存constrait,则将最低的文件写入exitfile,但是我不能让自己想办法做到这一点。循环约束和输入长达6个或更多关键字符的情况正在融化我的大脑。最后我只想要将初始的tobesorted.txt完全排序,一次将2个,3个或4个文件合并为一个更大的文件并继续下一个文件。这已经实现了,我只需要实现Merge功能。 对不起,如果我让自己太难理解,英语不是我的母语。感谢你们能给予的任何支持。
答案 0 :(得分:0)
如果您已经拆分并排序了原始的“块”文件,那么您需要的是这样的:
void mergeFiles(FILE* fIn1, FILE* fIn2, FILE* fOut)
{
int ch1;
int ch2;
ch1 = fgetc(fIn1);
ch2 = fgetc(fIn2);
// merge files
while ((ch1 != EOF) && (ch2 != EOF))
{
if (ch1 < ch2)
{
fputc(ch1, fOut);
ch1 = fgetc(fIn1);
}
else
{
fputc(ch2, fOut);
ch2 = fgetc(fIn2);
}
}
// write the rest of one of the files
if (ch2 == EOF)
{
while (ch1 != EOF)
{
fputc(ch1, fOut);
ch1 = fgetc(fIn1);
}
}
else
{
while (ch2 != EOF)
{
fputc(ch2, fOut);
ch2 = fgetc(fIn2);
}
}
fflush(fOut);
}
这个想法是合并排序算法的合并阶段要求您只获得两个子阵列中每个子阵列的第一个元素被合并。因此,流输入(例如文件)也符合这一要求(即,您不必将整个文件读入RAM!)。您所要做的就是读取两个已排序的char-by-char文件,比较这些字符,然后输出到目标文件中的较小者。然后再次合并这些新的组合文件,直到获得一个大的已排序文件。