在C++中对这些独立但相关的序列进行排序的干净方法是什么?

What's a clean way to sort these separate-but-related sequences in C++?

本文关键字:排序 是什么 方法 独立 C++      更新时间:2023-10-16

我有两个vector对象,它们包含以相同方式排序的不同类型的数据。我的情况看起来是这样的:

struct Info
{
    double opaque_data_not_relevant_to_this_problem[6];
    int data_len;
    bool operator<(const Info &rhs) const
    {
        return (bool) irrelevant_operation_on_opaque_data;
    }
};
vector<Info> vec1;
vector<double> vec2;

对于vec1中的每个Info条目,vec2包含一系列double值,其长度等于vec1中相应元素中data_len的值。例如:

vec1[0].data_len == 100 ==> vec2[0:99] correspond to vec1[0]
vec1[1].data_len == 150 ==> vec2[100:249] correspond to vec1[1]
// and so on

我知道这种安排不是很面向对象,可能有一种"更C++"的方法可以做到这一点。然而,我的环境中的其他限制迫使我使用这种类型的数据打包,所以我需要解决它。不幸的是,vec2中的每个数据记录的长度(由vec1中的data_len对应项指定)直到运行时才知道,并且长度因记录而异。

我的问题是:我想根据一些标准对这两个向量进行排序。对vec1进行排序很简单,因为我只需要使用std::sort。然而,同时,我需要对vec2进行排序,以使上述排序仍然保持(即,vec2中的第一个值块在排序后对应于vec1[0])。如果我能从排序过程中获得某种"索引向量",然后用它来重新排序vec2(原位或错位操作都可以),那就太好了,但我不确定用标准库(如果有的话)有什么好方法可以做到这一点。

我可以通过定义将两者捆绑在一起的第二个中间结构来进行分类:

struct SortableInfo
{
    Info info;
    vector<double> data;
    bool operator<(const SortabelInfo &rhs) const { return info < rhs.info; }
};
vector<SortableInfo> vec3;

然后,我会根据vec1vec2的内容适当地填充vec3,对其进行排序,然后再次将数据扇出以分离向量。然而,这似乎并不是特别有效。有什么更好的执行方法的建议吗?

您可以在SortableInfo中存储指向相应vec2 中起始位置的指针

struct SortableInfo {
    Info info;
    double *start_pos;
    bool operator<(const SortabelInfo &rhs) const { return info < rhs.info; }
}

填充您的vec3,对其进行排序,然后在最后使用排序的指针制作vec2的有序副本。

我不知道导致您以这种方式捆绑数据的具体约束是什么,但您的vec3选项接近于面向对象的做事方式。

我要做的是,首先只为你的结构(或类,取决于你的需求)制作一个向量,然后首先忘记单独的向量。

你不能这样做有什么特别的原因吗?

只在Info中保留一个偏移量?

struct Info
{
    int data_len;
    int offset;
    bool operator<(const Info &rhs) const
    {
        return (bool) irrelevant_operation_on_opaque_data;
    }
};

offset只是vec2中的偏移所以现在你可以有例如

vec1[0].offset = 350, vec1[0].data_len = 100 ==> vec2[350:450] = your data

如果你也想支持删除,你必须重新定义所有的offset,而这个解决方案可能没有那么有效。

现在,您只需排序,仍然可以使用offset来查找数据。


只需定义一个新的Struct并将其用作包装器。

struct ExtendedInfo
{
    Info info;
    int offset;
}