在multiset stl中的LowerBound

时间:2016-07-01 17:46:19

标签: c++ c++11 stl multiset

我试图通过使用:

找到多个集合中有多少元素小于某个X.
mset.lower_bound(X) - mset.begin()

但它没有用。任何解决方法?

2 个答案:

答案 0 :(得分:4)

您可以使用:

std::distance(mset.begin(), mset.lower_bound(X));

为了使其健壮,请使用:

size_t count = 0;
auto found = mset.lower_bound(X);
if ( found != mset.end() )
{
   count = std::distance(mset.begin(), found);
}

答案 1 :(得分:3)

如果频繁地计算低于下限的项目数,并且很少插入项目,则使用std::vector并使其保持排序可能会获得更好的性能。

特别是如果T是可移动的。

#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>



auto insert(std::vector<std::string>& v, std::string s)
{
    auto lb = std::lower_bound(v.begin(), v.end(), s);
    v.insert(lb, std::move(s));
}

int main()
{

    std::vector<std::string> v;
    insert(v, "goodbye");
    insert(v, "world");
    insert(v, "cruel");

    auto count = std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), "goodbye"));
    std::cout << count << std::endl;
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

}
  

但为什么仍然使用std :: distance与vector?

因为如果我们选择使用不同的容器类型进行分析,我们可能会改变主意,所以最好是惯用语。标准库包含确保成语最佳的专业化:

#include <vector>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>

template<class Range, class Value, class Pred = std::less<>>
auto lower_bound(Range&& range, Value&& v, Pred&& pred = Pred())
{
    return std::lower_bound(std::begin(range), std::end(range),
                            std::forward<Value>(v),
                            std::forward<Pred>(pred));
}

template<class Container>
auto insert(Container&& v, std::string s)
{
    auto lb = lower_bound(v, s);
    v.insert(lb, std::move(s));
}

template<class Range, class OutIter>
auto copy(Range&& range, OutIter dest)
{
    return std::copy(std::begin(range), std::end(range), dest);
}

auto test = [](auto&& container)
{
    insert(container, "goodbye");
    insert(container, "world");
    insert(container, "cruel");

    auto count = std::distance(std::begin(container), lower_bound(container, "goodbye"));
    std::cout << count << std::endl;
    copy(container, std::ostream_iterator<std::string>(std::cout, "\n"));

};

int main()
{
    test(std::vector<std::string>{});
    test(std::multiset<std::string>{});
}