使用 lambda 函数在 C++ 中按然后排序

Posted

技术标签:

【中文标题】使用 lambda 函数在 C++ 中按然后排序【英文标题】:sort by and then in c++ using lambda functions 【发布时间】:2018-01-10 08:15:27 【问题描述】:

在 C# 中给定一个结构:

struct Point int x, int y

我们可以这样写:

List<Point> list;
list.OrderBy(p => p.x).ThenBy(q => q.y);

如何使用 lambda 函数在 C++ 中表达这种逻辑?

【问题讨论】:

所以你想按x排序,然后按y @GauravSehgal 是的。 【参考方案1】:

看起来你也想对(y, x)1 进行字典排序。您可以利用库函数std::tie。那个返回一个引用元组,std::tuple 有一个小于运算符来执行字典比较。因此,您只需指定要比较项目的顺序。

这是 std::vector 的外观(您在 C++ 中转到容器类型,始终以 std::vector 开头):

std::vector<Point> my_list;
// Fill my_list
std::sort(begin(my_list), end(my_list), [](auto const& l, auto const& r)
  return std::tie(l.y, l.x) < std::tie(r.y, r.x);
);

1 - 我只是基于方法名称,所以这可能不是你真正想要的。

【讨论】:

Python 列表比链表更类似于 C++ 向量。 @n.m.- C# 列表呢? OP基于此询问。我自己对 C# 不太熟悉。 根据here,显然是一样的…… @Aconcagua - 相应地修改了答案。谢谢! 我的错,错误地假设了 Python,但显然 C# 列表也更像向量。【参考方案2】:

您可以使用 STL 函数 std::sort。示例:

struct point
    int x;
    int y;
;

// Compare function. This can be lambda function too.
bool comp(const point& a,const point& b) 
    if(a.x > b.x) return true;
    else if(a.x == b.x) return a.y > b.y;
    return false;



int main()    
    // v is vector (or any other container which can be iterated) containing points
    std::sort(v.begin(),v.end(),comp);

【讨论】:

你就是这样按x排序的。我猜你应该加If(a.x==b.x) return a.y&gt;b.y; 是的。我刚刚写了一些虚拟比较函数。但为了清楚起见,我会根据您的建议添加代码。 ((a.x &gt; b.x) and (a.y &gt; b.y)) 是错误且危险的比较,不适合排序。 @n.m.如果你能解释一下什么时候会出错,那就太好了。 考虑a.x &gt; b.x,但a.y &lt; b.y的情况。您的函数将为 comp(a, b)comp(b, a) 返回 false,这表明 ab 应该被视为相等。但他们显然不应该。【参考方案3】:

两种方式 - 要么排序两次,首先按 y,然后对 x 使用 stable 排序(请注意,这与 C# 中的完全相反!)。 std::sort 运气不好,虽然它不稳定,但幸运的是,正如 Benjamin 暗示的那样,还有 std::stable_sort...

另一种方法是确保两个点进行比较,从而首先应用 x 的差异,并且仅在相等的情况下才考虑 y:

std::sort
(
    // range to sort
    list.begin(), list.end(),
    // next the comparator - you wanted a lambda? OK, here it is:
    [](point const& a, point const& b)
    
        return a.x < b.x || a.x == b.x && a.y < b.y;
    
);

【讨论】:

std::sort 可能不稳定,但标准库中还有另一个功能。奇怪地命名为std::stable_sort @BenjaminLindley 感谢您的提示。第一种方法并没有应付太多,因为我认为第二种方法更胜一筹......【参考方案4】:

您只需将 lambda 函数指定为 std::list::sort()。您决定要如何排序。

list.sort([](Point  i,Point  j)
            
               if(i.x!=j.x)
                   return i.x<j.x;
               else
                   return i.y<j.y;
             
          );

【讨论】:

你最好用const Point &amp; @user2807083 实际上没有,在这种情况下 Point 在 x64 系统上是 sizeof == 8,所以复制它比使用引用更好

以上是关于使用 lambda 函数在 C++ 中按然后排序的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++ 在 OpenCV 中按深度维度排序

c++基础(lambda)

C++之lambda表达式的介绍

Lambda表达式

如何在 C++ 中按向量进行升序和降序排序

在C ++中按优先级升序对带有int和string的txt文件进行排序