【问题标题】:Java8 lambda type of comparisons in c++c++中Java8 lambda类型的比较
【发布时间】:2020-01-06 14:53:10
【问题描述】:

我有以下代码,它们按 Info 类的多个字段对 Info 实例列表进行排序。 Java8 中的 lambda 表达式使事情变得简单而干净。因此,我想知道在 C++ 中是否有类似的方法?如果不是,那么处理这种多字段排序的最接近(或最优雅的方式)是什么?谢谢!

    public class Info {
        Info(int wi, int bi, int di) {
            w = wi;
            b = bi;
            d = di;
        }

        int w = -1;
        int b = -1;
        int d = -1;
    }

    List<Info> results = new ArrayList<Info>();

    Collections.sort(results, (a,b) -> { 
            if (a.d == b.d) {
                if(a.w == b.w) {
                    return a.b-b.b;
                } else {
                    return a.w - b.w;
                }
            } else {
                return a.d - b.d;
            }
    });

【问题讨论】:

  • 建议试一试,然后回来在这里发帖。无论如何,即使使用 java 代码,您也可以比当前的实现做得更好。这是代码审查的问题,但是。
  • 你可以用谷歌搜索“C++ lambda”。

标签: java c++ algorithm sorting tuples


【解决方案1】:

例如,您可以为类定义运算符

这是一个演示程序

#include <iostream>
#include <tuple>
#include <list>

class Info 
{
public: 
    Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
    {
    }

    friend bool operator <( const Info &, const Info & );

    friend std::ostream & operator << ( std::ostream &, const Info &info )
    {
        return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }"; 
    }

private:    
    int w = -1;
    int b = -1;
    int d = -1;
};

bool operator <( const Info &a, const Info &b )
{
    return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
}

int main() 
{
    std::list<Info> lst = { { 1, 2, 3 },  { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };

    lst.sort();

    for ( const auto &item : lst ) std::cout << item << '\n';

    return 0;
}

它的输出是

{ 2, 1, 1 }
{ 2, 1, 3 }
{ 2, 2, 1 }
{ 3, 1, 2 }
{ 3, 2, 2 }

也就是说,您可以使用标准函数 std::tie 来完成所有工作。

或者用容器std::vector

#include <iostream>
#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>

class Info 
{
public: 
    Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
    {
    }

    friend bool operator <( const Info &, const Info & );

    friend std::ostream & operator << ( std::ostream &, const Info &info )
    {
        return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }"; 
    }

private:    
    int w = -1;
    int b = -1;
    int d = -1;
};

bool operator <( const Info &a, const Info &b )
{
    return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
}

int main() 
{
    std::vector<Info> v = { { 1, 2, 3 },  { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };

    std::sort( std::begin( v ), std::end( v ) );

    for ( const auto &item : v ) std::cout << item << '\n';

    return 0;
}

您可以使用 lambda 表达式,前提是您可以访问类的数据成员,例如通过成员函数。

#include <iostream>
#include <tuple>
#include <vector>
#include <iterator>
#include <algorithm>

class Info 
{
public: 
    Info( int wi, int bi, int di ) : w( wi ), b( bi ), d( di )
    {
    }

    int w = -1;
    int b = -1;
    int d = -1;
};

std::ostream & operator << ( std::ostream &, const Info &info )
{
    return std::cout << "{ " << info.d << ", " << info.w << ", " << info.b << " }"; 
}


int main() 
{
    std::vector<Info> v = { { 1, 2, 3 },  { 1, 1, 2 }, { 1, 3, 2 }, { 2, 1, 2 }, { 2, 2, 3 } };

    std::sort( std::begin( v ), std::end( v ), 
               []( const auto &a, const auto &b )
               {
                    return std::tie( a.d, a.w, a.b ) < std::tie( b.d, b.w, b.b );
               } );

    for ( const auto &item : v ) std::cout << item << '\n';

    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-07-09
    • 1970-01-01
    • 2023-03-26
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2014-08-19
    相关资源
    最近更新 更多