【问题标题】:Sorting a structure of arrays [duplicate]对数组结构进行排序[重复]
【发布时间】:2019-01-29 16:46:26
【问题描述】:

我有一些数据如下:

size_t num_elements = //...
some_type_t *data = //...
int *scores = //...

每个元素data[i]scores[i] 中都有对应的分数。我想对datascores 进行排序,使用scores 的数组对数据进行排序。

例如,对于数据:

data = {'d', 'g', 'i', 'a', 'p'}
scores = {3, 5, 1, 2, 4}

排序后的版本是

data = {'i', 'a', 'd', 'p', 'g'}
scores = {1, 2, 3, 4, 5}

有没有办法使用 C++ 标准库? 我宁愿不需要包含 Boost 或尚未标准化的库。

我还想避免不必要地复制数据。这包括将其转换为结构数组。

【问题讨论】:

  • 是的。函数名称为std::sort
  • @Someprogrammerdude 提供你自己的操作符
  • @eerorika 不,不是,OP 需要排序以同时移动 2 个容器中的元素,比较器对此无能为力。请仔细阅读问题。
  • @Slava 不需要同时移动它们。只要您不介意制作副本,为每个数组单独进行排序是微不足道的。但正如我所说,这不是最优的。此外,通过使用自定义迭代器,std::sort 可以同时移动 2 个容器中的元素。
  • 这个问题有几十个版本,如果链接的副本不适合你。

标签: c++ sorting


【解决方案1】:

假设没有理由不合并这两个数据数组,最简单的答案是将它们合并到带有重载运算符的structclass(可能是前者)中。然后,您可以定义这些结构/类的数组,将数据绑定在一起,以便将数据和分数一起移动。

struct ScoredData
{
   some_type_t data;
   int score;

  bool operator<(const ScoredData& right)
  {
      return this->score < right.score;
  }
}

(这个例子可以通过将some_type_t作为模板参数来扩展)

如果以这种方式组合这些是不可接受的,您可能会发现定义一个模仿这种行为的迭代器是成功的。

【讨论】:

  • 模仿行为的迭代器确实是票!但这是一段棘手的代码。
  • 这会起作用,但它会不必要地复制所有数据,我想避免这种情况。您能否详细说明迭代器的建议?
  • 这将涉及编写两个类:一个代表迭代器,一个代表它在取消引用时返回的值。值类需要为Swappable
  • 我做到了这一点,但我在某处出现错误,因为它一直超时:coliru.stacked-crooked.com/a/6d5be2fbd6f37f24
  • 我没有看到 less&lt;&gt; 的实际值类 - 您似乎只为迭代器本身定义了比较。
【解决方案2】:

另一种方法是创建一个索引数组(将其初始化为 0、1、2、3...)并使用score[a] &lt; score[b] 比较对其进行排序。

然后你需要根据索引重新排列分数和数据数组。比如排序后index[0] = 3,需要移动元素score[0] = score[3];数据[0] = 数据[3]。

很遗憾,当您重新排列时,我没有找到避免复制的方法。

【讨论】:

    【解决方案3】:

    你能把这些对的新数组中的元素分组,然后使用 sort 对其进行排序并在正确的对元素进行比较,然后从排序后的对数组中更新初始数组吗?


    更好

    你创建了一个由 score 值和索引 0 组成的一对向量,第一对是 0,第二个是 1,第三个是 2,依此类推,所以你不要复制数据

    qsort 考虑分数部分的情侣数组,之后您只需查看情侣中索引的新顺序即可对 scores数据轻松更新它们

    【讨论】:

    • 是的,但是效率极低:所有数据都需要复制两次。
    • @konsolas 你知道排序也会做一些复制
    • 但只有那些对数组进行排序所必需的,它不必暂时将用于存储数据的内存空间增加一倍。
    • 所有作为一个限制,如果你想避免定义你自己的 qsort :)
    • 问题询问是否有办法用标准库做到这一点。标准库完全能够对结构数组进行排序,而无需进行不必要的复制。
    猜你喜欢
    • 1970-01-01
    • 2012-10-27
    • 2022-11-15
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    相关资源
    最近更新 更多