使用结构对二进制文件进行排序

问题描述 投票:0回答:1

我正在开发一个 C++ 程序,该程序处理存储在二进制文件中的 Pokémon 数据。该程序从二进制文件中读取神奇宝贝记录,根据它们的能力对它们进行排序,然后将排序后的神奇宝贝写回到另一个二进制文件中。但是,我在排序功能方面遇到了问题。

struct Pokemon
{
    char Name[50];

    int Type;

    unsigned Power;
};

sortPokemons 函数正在接收一个输入流,该输入流与包含神奇宝贝(未排序)的二进制文件关联,以及一个输出流,该输出流与我们应该存储排序的神奇宝贝(按其

Power
)的文件关联。

void sortPokemons(std::istream& is, std::ostream& os)
{
    unsigned count = 1;

    while (true)
    {
        Pokemon p = readPokemonFromBinary(is);

        if (is.eof())
        {
            break;
        }

        Pokemon min;
        min.Power = INT32_MAX;

        while (true)
        {
            Pokemon c = readPokemonFromBinary(is);

            if (is.eof())
            {
                break;
            }

            if (c.Power < min.Power)
            {
                min = c;
            }
        }

        printPokemon(min);

        is.clear(); //the eof bit is set for the inner while to end
        is.seekg(count * sizeof(Pokemon), std::ios::beg);
        count++;
        writePokenomToBinary(min, os);
    }
}

请注意,我们知道输入文件中仅包含连续的神奇宝贝记录。

以下算法不起作用,我想我知道为什么:我正在尝试模拟选择排序算法,但为了让它工作,我们需要在需要时交换元素,我不知道如何使用只有文件。是否有更优雅的方法来实现我的目标(一个新文件,其中包含按

Power
升序排列的神奇宝贝)?我的想法有效吗?

c++ sorting file-io binary-data
1个回答
0
投票

嗯。对输入流的随机访问。这可能吗?没想到啊。

但即使对您的文件类型进行随机访问,您的算法也存在缺陷。第一次循环时,您将读取整个输入文件并找到功率最低的文件,然后将其写出。伟大的。到目前为止你都很好。

第二次通过外循环时,您将跳过输入的第一条记录。但除非您的输入已经排序,否则您跳过的输入可能是文件中的下一个最低值。

我会用完全不同的方式来做这件事。我们假设输入流上可以进行随机访问。我将文件读入 std::vector 一次。你说由于记忆问题你不想这么读。 (它必须是一个非常大的文件,才会成为一个问题。)但是您可以存储一个简单的结构:

struct PowerIndex {
     size_t index;
     long power;
}

只需存储索引(计数)0..n 加上您读取的记录的幂。

然后排序。现在,您可以运行该向量,寻找正确的文件位置,读取记录,写入记录,然后就完成了。

而且它会是正确的。

当然,我仍然想知道通用的随机访问是否可用

std::stream

© www.soinside.com 2019 - 2024. All rights reserved.