简体   繁体   English

对结构向量进行二进制搜索

[英]Binary search on the vector of structs

I have a vector of structs that contains struct with this architecture 我有一个包含该结构的结构的结构向量

struct Main{

   int mainID;
   string mainDIV;
   string mainNAME;

}

is it possible to use binary search on struct? 有可能在结构上使用二进制搜索吗? I know its easy to use on value using 我知道它易于使用

binary_search( vector.begin() , vector.end() , 5 )

But is there a way how to pass callback or something to actually find attribute of struct? 但是有没有一种方法可以通过回调或实际找到struct属性的方法呢? I fail to find anything related to thi topic. 我找不到与该主题有关的任何内容。

Yes, it's possible. 是的,有可能。 The value that std::binary_search takes is only meaningful when compared to the elements of the container. valuestd::binary_search相比时容器中的元素需要才有意义。 In the simple case (if Main supports operator< somewhere), you would provide an element of type Main as the value: 在简单的情况下(如果Main支持某个地方的operator< ),您将提供Main类型的元素作为值:

// check if this specific Main exists
bool yes = std::binary_search(v.begin(), v.end(), Main{0, "some", "strings"});

// does exactly the same thing as above
bool yes = std::binary_search(v.begin(), v.end(), Main{0, "some", "strings"}
    , std::less<Main>{});

If it doesn't support operator< (or your container is ordered by something else, eg mainID ), then you will have to provide a comparator yourself that the algorithm will use: 如果它不支持operator< (或您的容器由其他东西排序,例如mainID ),那么您将必须自己提供一个比较器,该算法将使用:

// check if there is a Main with mainID 5
bool yes = std::binary_search(v.begin(), v.end(), 5,
    [](const Main& element, const int value) {
        return element.mainID < value;
    });

You have to provide information to binary_search() to tell it how to compare your objects. 您必须向binary_search()提供信息,以告诉它如何比较对象。 The two most common ways, are to either add an operator<() to the struct if that is possible, or provide a helper function that can compare two struct s. 两种最常见的方法是,如果可能的话,将operator<()添加到struct ,或者提供可以比较两个struct的辅助函数。

The first form would look something like this: 第一种形式如下所示:

struct Main {
  int mainID ;
  string mainDIV ;
  string mainNAME ;
  bool operator<(const Main & other) const
  {
    return mainID < other.mainID ;
  }
}

This will only compare on on mainID , but you can expand it from there. 这只会在mainID上进行mainID ,但是您可以从那里进行扩展。

Also, this only teaches the compiler how to compare two struct Main , while @Barry's answer above will match an int and a struct Main . 此外,这仅教编译器如何比较两个struct Main ,而上面@Barry的答案将匹配int和struct Main But lets keep going with this answer. 但是,让我们继续这个答案。

Now to find the record for 5 , we have to make it into a struct Main : 现在要查找5的记录,我们必须将其放入struct Main

struct Main search_key = { 5 } ;
bool yes = std::binary_search( v.begin(), v.end(), search_key ) ;

Now, this isn't very elegant, and besides if you have a constructor for struct Main ( and haven't put it in your example ), this won't even work. 现在,这不是很优雅,此外,如果您具有struct Main的构造struct Main (并且未在示例中放置它),那么它甚至将无法工作。 So we add another constructor just for int . 因此,我们为int添加了另一个构造函数。

struct Main
{
    Main(int id, const string & a_div, const string & a_name ) : id(id), div(a_div), name(a_name) { }
    Main(int id) : id(id) { }
    int id ;
    string div, name ;

    bool operator<(const Main &o) const { return id < o.id ; }
} ;

Now we can do a slightly shorter form: 现在我们可以做一个简短的表格:

bool has_3 = std::binary_search( v.begin(), v.end(), Main( 3) ) ;

Historical note: Bjarne has been trying for quite some time to get default comparison operators into the standard, but not everyone was excited about it at the standards meetings. 历史记录:Bjarne一直在尝试将默认比较运算符纳入标准,但并非所有人都对标准会议感到兴奋。 I though there was some progress on it at the last meeting and so it may eventually appear when C++17 is a thing. 我在上次会议上虽然取得了一些进展,所以最终可能在C ++ 17出现时才出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM