簡體   English   中英

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

[英]Using lower_bound, upper_bound, and binary_search to find the object with an equal member field

我有一個看起來像這樣的結構,

struct Foo {
    int a;
};

我有這些結構的矢量,看起來像這樣,

vector<Foo> foos;

所有Foo都使用STL sort()函數按整數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,這個構造函數可以在任何地方使用代碼)。 但如果這是唯一的選擇,我會接受它。

您可以為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);

在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);

讓您的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排序FooSortHelper 通過允許它從int構造,我允許Fooint無縫地進行比較。

我提到的另一種方法是創建一個類,其中每個Fooint (所有4個)都重載了operator()。 我發現以上更容易。

如果要排序的類型復制起來很昂貴(例如std::string ),則FooSortHelper可以存儲對所述字段的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM