我想根据元素之间与索引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]的访问权限?
答案 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;
}