使用lower_bound,upper_bound和binary_search查找具有相等成员字段的对象

时间:2012-11-13 01:52:07

标签: c++ search stl

我有一个看起来像这样的结构,

struct Foo {
    int a;
};

我有这些结构的矢量,看起来像这样,

vector<Foo> foos;

使用STL sort()函数,所有Foo都按整数a按升序排序。现在我想获得成员字段Foo小于或等于给定数字的a对象,如STL lower_bound()函数。问题是STL lower_bound函数声明如下所示:

template <class ForwardIterator, class T, class Compare>
  ForwardIterator lower_bound ( ForwardIterator first, ForwardIterator last,
                                const T& value, Compare comp );

所以,虽然我想做点什么,

lower_bound(foos.begin(), foos.end(), 5, custom_comp);

我不能,因为我正在寻找的int(在这种情况下为5)不属于Foo类型。我在使用lower_bound(),upper_bound()和binary_search()时遇到此问题。 custom_comp仅定义排序,并未定义a = 5的对象实际上等于int 5。

使用STL有没有优雅的方法?

编辑:

我意识到我的例子并不完全代表我的问题。我实际拥有的是Foo包含两个整数,a和b。当我调用lower_bound时,我无法访问b(因为我不关心它)。现在billz回答的问题是我必须定义一个只使用a作为参数的构造函数,在我看来这不是很优雅(因为b未定义或者是abitrary,这个构造函数可以可以在代码中的任何地方使用)。但如果这是唯一的选择,我会接受它。

3 个答案:

答案 0 :(得分:3)

您可以为struct Foo

提供构造函数
struct Foo {
  Foo(int x):a(x){
  }
    int a;
};

您现在可以致电:

std::lower_bound(foos.begin(), foos.end(), 5, custom_comp);

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);

Foo f(5);
std::lower_bound(foos.begin(), foos.end(), f, custom_comp);

建议的方法是:

struct Foo {
  explicit Foo(int x):a(x){
  }
    int a;
};

std::lower_bound(foos.begin(), foos.end(), Foo(5), custom_comp);

答案 1 :(得分:1)

在C ++ 11中,您可以使用以下内容:

std::lower_bound(foos.begin(), foos.end(), Foo{5},
    [](const Foo& f1, const Foo& f2) { return f1.a < f2.a; });

或者在C ++ 03中:

Foo f = {5};
std::lower_bound(foos.begin(), foos.end(), f, custom_comp);

答案 2 :(得分:0)

让custom_comp同时接受fooint作为参数。这意味着它需要是一个仿函数,或者它可以采用foo_sort_helper个参数(可以从intfoo构建)并对它们进行排序。

或者,要明确:

struct FooSortHelper
{
  int ordering;
  FooSortHelper( Foo const& foo ):ordering(foo.value) {}
  FooSortHelper( int i ): ordering(i) {}
  FooSortHelper( FooSortHelper const& other):ordering(other.ordering) {}
  bool operator<( FooSortHelper const& other ) { return ordering < other.ordering }
};

auto lower = std::lower_bound( vec.begin(), vec.end(), 5,
  []( FooSortHelper left, FooSortHelper right ) {
    return left < right;
  }
);

您了解我如何封装FooFooSortHelper的排序方式?通过允许它从int构造,我允许Fooint无差别地进行比较。

我提到的替代方法是创建一个类,其中每个Fooint(所有4个)都重载了operator()。我发现上述内容更容易。

如果要排序的类型复制起来很昂贵(例如std::string),FooSortHelper可以存储对所述字段的引用。