【问题标题】:Binary search on vector objects of an element greater than an attribute对大于属性的元素的向量对象进行二分搜索
【发布时间】:2017-01-18 16:24:01
【问题描述】:

我有一个向量,其中包含我的类 X 的许多元素。 我需要在这个向量中找到一个元素的第一次出现,比如 S 使得 S.attrribute1 > someVariable。 someVariable 不会被修复。我该怎么做 binary_search 呢? (不是 c++11/c++14)。我可以用更大的搜索功能编写 std::binary_search (理想情况下,这意味着检查相等性)但那会错吗?什么是快速搜索的正确策略?

【问题讨论】:

标签: c++


【解决方案1】:

根据定义,只有当向量按根据二分搜索的谓词排序时,才能进行二分搜索。

所以,除非你的向量中的所有元素“S.attribute1 > someVariable”都位于所有不是的元素之后,否则这将是一个非首发,就在门。

如果向量中的所有元素都以其他方式排序,那么“其他方式”是唯一可以实现的二进制搜索。

假设它们是,您必须使用某种比较器,该比较器在属性上指定严格的弱排序,以便首先提出您的排序向量:

class comparator {

public:
    bool operator()(const your_class &a, const your_class &b) const
    {
          return a.attribute1 < b.attribute1;
    }
};

诀窍是,如果你想单独使用属性值进行搜索,你需要使用一个可与std::binary_search 一起使用的比较器,即defined as follows

template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last,
                    const T& value, Compare comp );

要使 std::binary_search 成功,范围 [first, last) 必须是 至少部分有序,即它必须满足以下所有条件 要求:

对于所有元素,如果 element

所以,唯一的要求是 comp(value, element)comp(element, value) 需要工作。您可以传递T 的属性值,而不是向量中的整个元素进行搜索,只要您的比较器可以处理即可:

class search_comparator {

public:
    bool operator()(const your_class &a, const attribute_type &b) const
    {
          return a.attribute1 < b;
    }

    bool operator()(const attribute_type &a, const your_class &b) const
    {
          return a < b.attribute1;
    }
};

现在,您应该可以使用search_comparator 代替comparator,并按属性值进行二分搜索。

而且,正如我所说,如果向量没有按给定属性排序,那么所有的赌注都会被取消。在这种情况下,您需要首先明确地使用std::sort,或者提出一些自定义容器,以正确的顺序单独跟踪向量元素,并且除了包含它们的主向量之外。也许使用指针,在这种情况下,您应该能够使用类似的搜索比较器对指针本身执行二进制搜索,而不是查看指针。

【讨论】:

    【解决方案2】:

    要使std::binary_search 成功,需要对范围进行排序。std::binary_searchstd::lower_bound 适用于已排序的容器。因此,每次您在 vector 中添加新元素时,都需要对其进行排序。

    为此,您可以在插入时使用std::lower_bound

    class X;
    class XCompare
    {
    public:
        bool operator()(const X& first, const X& second) const
        {
            // your sorting logic
        }
    };
    
    X value(...);
    auto where = std::lower_bound(std::begin(vector), std::end(vector), value, XCompare());
    vector.insert(where, value);
    

    您可以再次使用std::lower_bound 在您的向量中进行搜索:

    auto where = std::lower_bound(std::begin(vector), std::end(vector), searching_value, XCompare());
    

    别忘了检查std::lower_bound是否成功:

    bool successed = where != std::end(vector) && !(XCompare()(value, *where));
    

    如果你只想知道元素在向量中,或者直接使用std::binary_search

    【讨论】:

      猜你喜欢
      • 2013-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 2022-01-24
      相关资源
      最近更新 更多