【问题标题】:std::sort and custom swap functionstd::sort 和自定义交换函数
【发布时间】:2012-08-19 20:35:30
【问题描述】:

我目前有一个 pair<double, int> 数组,我使用简单的自定义比较器函数对其进行排序,例如

// compare by first
int sort_index_lcomparator(const pair<double, int>& a, const pair<double, int>& b) {
    return a.first < b.first;
}
// then sort simply like
pair<double, int> arr[size];
std::sort(arr, arr + size, sort_index_lcomparator);

我实际上对索引顺序感兴趣,而不是排序的双精度数。我的问题是我想改变这个结构,取而代之的是两个数组的结构而不是一个结构的数组,即我想优化局部性和自动矢量化,但在这种情况下我需要一个重载的@987654323 @ 它专门附加到一个类型。我想我需要为double 类型重新定义swap 并在这种自定义swap 中保持两个数组同步。有没有办法在有限的范围内以这种方式“覆盖”swap

【问题讨论】:

    标签: c++ stl std


    【解决方案1】:

    我有一个建议给你:让索引数组成为你排序的数组,并将值保留为全局数组。从那时起:根据接受索引的比较器进行排序,但实际上是根据值进行比较。

    【讨论】:

    • 但是稍等...交换将交换索引并忽略双打,所以两者会去相关不是吗? :(
    • 您不需要立即交换它们。首先对索引进行排序,就像交换双精度数和索引一样,然后您可以重建排序的双精度数组。毕竟第 i 个 double 将始终与索引 i 配对。为什么要一直将它们一起移动?
    • 我需要将它们一起移动,因为一旦第一次交换调用发生(交换由 std 而不是我在内部调用)排序的一致性被破坏,即你得到不正确的排序结果。
    • 不是这样的。假设您有索引数组idx 和双精度数d。然后你交换idx[i]idx[j] iff d[idx[i]] &lt; d[idx[j]]。这意味着最终不会有d[idx[i]] > d[idx[j]] for i &lt; j。所以索引会按照d的值排序。
    • ahhh 明白了...我现在明白了,使用像这样的比较器d[idx[i]] &lt; d[idx[j]],有道理,再次感谢您!
    【解决方案2】:

    您应该使用您的自定义“比较器”专门化 std::sort

    template <class RandomAccessIterator, class Compare>
    void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
    

    默认情况下sort 使用标准比较器,它只比较给定迭代器引用的元素。

    使用自定义 Compare 您可以覆盖它。请注意,它 不是 函数(在 C++ 中,您通常不能将函数作为模板参数传递)。这是class。您将此类的一个对象传递给sort,而该对象应实现以下运算符:

    bool operator () (const Type1 &a, const Type2 &b);
    

    因此,您可以为您的double 的数组调用sort。您的比较器应该有指向两个数组开头的指针:doubleint

    对于数组,迭代器解析为指向数组元素的指针。使用数组起始地址,您可以将其转换为索引,并使用它来访问第二个数组。

    【讨论】:

    • 但这里的关键不是自定义比较器,即使我有两个可用的指针,就像鲍里斯建议的那样。问题是swap。如果 std::sort 调用 swap 时,我可以访问这两个指针并不重要,这两个数组将去相关。
    • 另外,你可以使用函数作为模板参数,只要它们可以在编译时解析。
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 2020-10-02
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多