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

时间:2016-03-26 18:14:53

标签: c++ vector struct binary-tree

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

struct Main{

   int mainID;
   string mainDIV;
   string mainNAME;

}

是否可以在struct上使用二进制搜索?我知道它易于使用

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

但有没有办法如何传递回调或其他东西来实际找到struct的属性?我找不到与这个主题有关的任何内容。

2 个答案:

答案 0 :(得分:4)

是的,这是可能的。 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;
    });

答案 1 :(得分:4)

您必须向binary_search()提供信息,告诉它如何比较您的对象。两种最常见的方法是,如果可能的话,将operator<()添加到struct,或者提供可以比较两个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的时候。