基于3个对象的自定义排序

时间:2018-07-28 09:39:42

标签: c++

我想根据元素之间与索引0处的元素之间的相似性对2D数组进行排序。

如何定义可以使用外部第3个对象(索引为0的元素)的自定义排序功能?

比较功能需要执行以下操作

bool compare(float *a, float *b) {
    float *source = 2DArray[0];
    return distance(source, a) > distance(source, b);
}

调用时

std::sort(std::begin(2DArray), std::end(2DArray), compare);

显然无法访问2DArray。

如何编写该代码,以便对象可以调用函数来调用sort函数并授予对2DArray [0]的访问权限?

3 个答案:

答案 0 :(得分:1)

最简单的方法应该是创建一个Comparer类,如下所示:

struct Comparer {
    float *source;
    bool operator()(const float* a, const float* b) {
        return distance(source, a) > distance(source, b);
    } 
};

创建实例

Comparer compare;
comparer.source = 2DArray;

并将其传递给std::sort

std::sort(std::begin(2DArray), std::end(2DArray), compare);

捕获source指针的lambda函数将是更现代的方法。

最终还是差不多,但是捕获将被包装到由编译器生成的匿名类中。

答案 1 :(得分:1)

因此,如果我理解正确,您想按到固定点的距离排序。之所以可行,是因为该指标将为您提供“严格的弱顺序”(https://en.wikipedia.org/wiki/Weak_ordering),这是任何比较运算符用于排序所必需的。

但是,您的实际问题是:排序通常是一维的,因为它只给您一个A小于B的关系,您不能轻易地将其映射到2D。因此,您需要的是一个关于如何线性排列2d结构的想法,具体取决于其表示的内容。 (那么您可以有一个“开始”和“结束”)

我的建议是:首先转换为一维结构,例如只需附加2d数组的所有行,然后对其进行排序。之后,您可以考虑如何在2d中表示它们(如果适用)。 (或者至少在您的结构上具有定义的1d视图)

如果您详细了解实际的问题,我也许能够提供更具体的建议。

答案 2 :(得分:1)

假定您具有一些可以测量“元素之间的相似性”的函数,则可以使用lambda将该函数用作排序的谓词。

#include <iostream>
#include <algorithm>
#include <array>
#include <vector>

int dist2(const std::array<int, 2> &a, const std::array<int, 2> &b) {
    auto dx = a[0] - b[0];
    auto dy = a[1] - b[1];
    return dx * dx + dy * dy;
}

int main() {
    int x, y;
    std::vector<std::array<int, 2>> tab;

    while (std::cin >> x >> y) {
        tab.push_back({ x, y });
    }

    auto origin = tab.front();

    std::sort(std::begin(tab), std::end(tab), 
              [&origin](const auto &a, const auto &b) {
                  return dist2(a, origin) < dist2(b, origin);
              });

    for (const auto &a : tab) {
        std::cout << a[0] << ", " << a[1] << '\n';
    }

    return 0;
}

https://wandbox.org/permlink/5pWL2N5AOHcr20Wi