std :: lower_bound和std :: set :: lower_bound之间的差异

时间:2011-09-20 17:03:00

标签: c++ stl tree set lower-bound

C ++草案说明了std :: lower_bound:

§ 25.4.3.1 lower_bound [lower.bound]  
template<class ForwardIterator, class T>  
ForwardIterator lower_bound(ForwardIterator first, 
                            ForwardIterator last, 
                            const T& value);  
template<class ForwardIterator, class T, class Compare>  
ForwardIterator lower_bound(ForwardIterator first, 
                            ForwardIterator last, 
                            const T& value, 
                            Compare comp);  

Requires: The elements e of [first,last) shall be partitioned with respect 
    to the expression e < value or comp(e, value).
Returns: The furthermost iterator i in the range [first,last] such that for 
    any iterator j in the range [first,i) the following corresponding 
    conditions hold: *j < value or comp(*j, value) != false.
Complexity: At most log2(last − first) + O(1) comparisons.

请注意,这允许(通过暗示)比较不同(但可比较)的类型而不是*ForwardIterator将返回,但迭代器进度的数量没有复杂性限制。 (对于基于节点的容器,这将是O(最后 - 第一个)迭代器推进。)

§ 23.4.6.1
class set { 
   ...
    iterator lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
   ...
}

标准没有详细说明这些函数,但暗示这些函数用于O(log2(最后 - 第一个))比较和改进,但要求搜索关键字与包含的类型相同。

所以我的问题是:
(1)有没有办法获得std::set::lower_bound的速度和搜索类型std::lower_bound的灵活性? (2)为什么std::lower_bound不需要std::set::iterator专门用于std::lower_bound? (3)是否存在std::set::iterator 专门用于template< class Key, class Comp, class Alloc, class Lookup> std::set<Key, Compare, Alloc>::const_iterator lower_bound( std::set<Key, Comp, Alloc>::const_iterator begin, std::set<Key, Comp, Alloc>::const_iterator end, const Lookup& find, Compare comp); template< class Key, class Comp, class Alloc, class Lookup> std::set<Key, Compare, Alloc>::iterator lower_bound( std::set<Key, Comp, Alloc>::iterator begin, std::set<Key, Comp, Alloc>::iterator end, const Lookup& find, Compare comp); 的实现,或者有没有理由不这样做?

我希望找到类似的东西:

template < class Key, class Compare = less<Key>, class Allocator = allocator<Key> >
class set {
   ...
    template<class Lookup>
    iterator lower_bound(const Lookup& x);
    template<class Lookup>
    const_iterator lower_bound(const Lookup& x) const;
   ...
}

或:

{{1}}

但我怀疑它是否存在。显然,所有这些都可以扩展到其他基于树的容器和其他算法。我自己编写代码,但它需要我使用特定于实现的代码。这个想法来自这个问题:Efective search in set with non-key type

1 个答案:

答案 0 :(得分:4)

根据构造时给出的比较对象对std::set容器进行排序。当调用std::lower_bound时,无法检查它是否传递了匹配的比较对象,因此实现无法知道是使用标准算法还是专门设置的算法,因为后者仅在使用用于集合排序的比较对象(或者给出相同结果的对象)。

您添加的两个示例原型不起作用:

  1. 专门研究std::lower_bound以处理std::set迭代器:

    由于上面给出的原因,这不起作用:无法检查给定的比较对象是否与set的构造函数中给出的对象匹配。您的原型仅检查比较对象的类型是否匹配,但可以存在相同类型的不同比较对象。

  2. 使std::set::lower_bound采用模板参数:

    这可能使它与集合的比较对象不兼容,因为该对象的operator()通常不会被模板化,并且只需要T类型的参数。