对结构向量的二进制搜索

Binary search on the vector of structs

本文关键字:二进制 搜索 向量 结构      更新时间:2023-10-16

我有一个结构向量,其中包含具有此架构的结构

struct Main{
   int mainID;
   string mainDIV;
   string mainNAME;
}

可以对struct使用二进制搜索吗?我知道使用很容易实现价值

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

但有没有一种方法可以通过回调或其他方法来实际找到结构的属性?我找不到任何与这个话题有关的东西。

是的,这是可能的。std::binary_search采用的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>{});

如果它不支持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;
    });

您必须向binary_search()提供信息,告诉它如何比较您的对象。两种最常见的方法是,如果可能的话,在struct中添加一个operator<(),或者提供一个可以比较两个struct的辅助功能。

第一种形式看起来像这样:

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

这只会在mainID上进行比较,但您可以从那里展开它。

此外,这只教编译器如何比较两个struct Main,而@Barry上面的答案将匹配int和struct Main。但让我们继续这个答案。

现在要找到5的记录,我们必须将其制作成struct Main:

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

现在,这不是很优雅,而且如果你有struct Main的构造函数(并且还没有把它放在你的例子中),这甚至都不起作用。因此,我们只为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 ; }
} ;

现在我们可以做一个稍短的形式:

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

历史笔记:Bjarne已经尝试将默认比较运算符纳入标准相当长一段时间了,但在标准会议上并不是每个人都对此感到兴奋。我认为在上次会议上在这方面取得了一些进展,所以当C++17成为一种东西时,它可能最终会出现。