自定义排序元组的向量

16 c++ c++11

我有一个像元组的向量

vector<tuple<T1, T2, T3>> v;
Run Code Online (Sandbox Code Playgroud)

我相信当默认比较为元组类型启动时,它会执行字典比较.

我可以按照我选择的元素进行比较吗?例如,通过上面例子中的第二个元素或者包含m个类型的元组中的第i个元素?

先感谢您.

Nik*_*iou 20

有很多方法可以做到这一点,我使用的方法归结为声明自定义比较对象,实际上如下

// Functor to compare by the Mth element
template<int M, template<typename> class F = std::less>
struct TupleCompare
{
    template<typename T>
    bool operator()(T const &t1, T const &t2)
    {
        return F<typename tuple_element<M, T>::type>()(std::get<M>(t1), std::get<M>(t2));
    }
};
Run Code Online (Sandbox Code Playgroud)

适用于任意长度的元组 (避免使用可变参数模板 - 即使以可变方式执行它相当容易和安全,因为您可以将operator()的参数声明为任意长度的元组)并且也适用于对,并且您可以通过它是一个自定义比较函数/对象,但使用<运算符作为默认策略.一个示例用法是

int main()
{
    vector<tuple<int, string>> v;
    v.push_back(make_tuple(1, "Hello"));
    v.push_back(make_tuple(2, "Aha"));

    std::sort(begin(v), end(v), TupleCompare<0>());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有一种更现代的方式,通过使用lambdas,所以排序线将是

std::sort(begin(v), end(v), 
    [](tuple<int, string> const &t1, tuple<int, string> const &t2) {
        return get<0>(t1) < get<0>(t2); // or use a custom compare function
    }
);
Run Code Online (Sandbox Code Playgroud)

我相信值得为此创建一个函数对象(避免大量的样板代码)并采用第一种方法


编辑

由于Yakk的评论(在c ++ 1y上)符合标准(c ++ 14),我们在下面展示了通用lambda的情况

std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
        return get<0>(t1) < get<0>(t2); // or use a custom compare function
});
Run Code Online (Sandbox Code Playgroud)

这极大地匹配的力学TupleCompare由于operator()是模板也是如此.


Jen*_*unk 10

你可以这样做

#include <tuple>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

vector<tuple<int, float, char>> v;

int main() {
  v.push_back(std::make_tuple(1,1.2,'c'));
  v.push_back(std::make_tuple(1,1.9,'e'));
  v.push_back(std::make_tuple(1,1.7,'d'));

  sort(v.begin(),v.end(),
       [](const tuple<int,float,char>& a,
       const tuple<int,float,char>& b) -> bool
       {
         return std::get<1>(a) > std::get<1>(b);
       });

  cout << std::get<2>(v[0]) << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ckl 4

是的,您可以在需要时在 C++ 中定义自定义排序。我想你需要它std::sort,对吧?std::sort准确地说,请查看算法的第二个版本的文档,即采用comp参数的版本。

您必须定义一个小于函子,如下所示:

struct CustomLessThan
{
    bool operator()(tuple<T1, T2, T3> const &lhs, tuple<T1, T2, T3> const &rhs) const
    {
        return std::get<1>(lhs) < std::get<1>(rhs);
    }
};
Run Code Online (Sandbox Code Playgroud)

然后将其用于std::sort

std::sort(v.begin(), v.end(), CustomLessThan());
Run Code Online (Sandbox Code Playgroud)

在 C++11 中,您可以通过使用lambda而不是创建命名结构来缩短代码。cppreference.com 上给出的示例也展示了这种技术。