C++中的多键自定义排序

Multi-Key Custom Sorting in C++

本文关键字:自定义 排序 C++      更新时间:2023-10-16

问题陈述:

我想使用自定义排序条件对结构的std::vector进行排序。

结构为:

struct Node
{
   int x;
   int y;
   float value;
};

矢量为:

std::vector<Node> vec;

我的自定义排序标准是,矢量应首先按y排序,然后按x排序(就像在 Microsoft Excel 中一样)。

例:

输入:

x y
5 6
2 4
1 1
1 0
8 10
4 7
7 1
5 4
6 1
1 4
3 10
7 2

输出:

x y
1 0
1 1
6 1
7 1
7 2
1 4
2 4
5 4
5 6
4 7
3 10
8 10

上述排序可以通过任何C++标准库排序功能来实现吗?如果没有,还有其他可以使用的库吗?

是的,您可以使用std::sort比较函数来做到这一点。

bool comparison(const Node& node1, const Node& node2)
{
    if (node1.y < node2.y) return true;
    if (node1.y == node2.y) return node1.x < node2.x;
    return false;
}
int main() {
    std::sort(vec.begin(), vec.end(), comparison);
}

通常,当需要字典排序时,为多个字段实现比较运算符(和函数)更清楚地表示为领带。

static bool compare(Node const& l, Node const& r) {
    // Note the alignment so that both expressions only differ in their `l` and `r` ?
    return std::tie(l.y, l.x)
         < std::tie(r.y, r.x);
}

但是,即使这样,也会留下一些重复和不一致的路线。以下帮助程序负责:

static std::tuple<int&,int&> tuplize(Node const& n) { return std::tie(n.y, n.x); }

然后可以简单地应用:

static bool compare(Node const& l, Node const& r) {
    return tuplize(l) < tuplize(r);
}

塔阿达姆:)

从 C++11 开始,您还可以使用 lambda 表达式而不是定义比较函数:

std::sort(std::begin(vec), std::end(vec), [](const Node& a, const Node& b) {
    return a.y < b.y || (a.y == b.y && a.x < b.x);
});

这样,您可以保持代码相当简短。

Ideone上的代码

std::sort采用自定义比较函数。我还没有测试过这个,但你的可能看起来像这样:

bool cmp (const Node& lhs, const Node& rhs)
{
    if ( lhs.y < rhs.y ) return true;
    else if ( lhs.y == rhs.y ) return ( lhs.x < rhs.x );
    else return false;
}