有效地计算两个std :: multimap迭代器之间的条目数

时间:2014-03-25 20:22:00

标签: c++ c++11 stl time-complexity multimap

我想在少于O(N)的时间内计算std::multimap的两个迭代器之间的条目数。是否有任何技巧或巧妙的方法来做到这一点?

由于std::multimap具有双向迭代器,我的理解是像std::distance这样的东西可以在O(N)时间内完成。

其他详细信息:multimap的密钥是N元组。我正在尝试找到multimap中键的第一个元素为0的条目数。它们键的第一个元素的选项是0和1,而multimap使用严格的弱排序其中键的第一个元素始终是最重要的。即所有带0的元素都来自任何带有1的元素。

上下文:迭代器由equal_range返回,它以对数时间运行。据说,我想测量范围的长度。

谢谢。

2 个答案:

答案 0 :(得分:5)

您正在寻找的是N3465中提出的所谓的heterogeneous comparison lookup。它允许在equal_range成员函数中使用不同但兼容的比较函数来存储Key。在您的情况下,查找比较运算符(第一个元组成员)将与元组词典比较不同但是一致。

不幸的是,根据this Q&A,只有一小部分论文被C ++ 14标准草案所接受。但是,N3465论文的作者也是已实施this feature的Boost.MultiIndex的作者。您可以按照Boost.MultiIndex文档emulate a std::multimap进行操作。

一旦使用了改编后的equal_range的通用boost::multiindex_container成员函数,就可以在返回的迭代器上执行std::distance()。复杂性在equal_range的容器大小中是对数的,并且在返回的迭代器范围的大小中是线性的。如果您对结果不感兴趣,但只对计数感兴趣,那么还有一个广义的count()成员函数返回相同的对数+线性时间。

答案 1 :(得分:0)

您想使用Iterator库中的std::distance方法。引用位于std::distance。以下是主要参考:Iterator library

描述截至2014年3月25日:

template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type
    distance( InputIt first, InputIt last );

返回第一个和最后一个之间的元素数。

如果无法从最初(可能重复)先递增到最后一次,则行为未定义。

参数
first - 迭代器指向第一个元素
last - 指向最后一个元素的迭代器

类型要求
- InputIt必须满足InputIterator的要求。操作更有效       如果InputIt另外满足RandomAccessIterator的要求

返回值
第一个和最后一个之间的元素数。

复杂性
线性。
但是,如果InputIt另外满足RandomAccessIterator的要求,则复杂性常量


请注意,上述细节可能会有所变化。通过直接导航到std::distance参考页面,可以获得最准确的信息。

来自std::distance参考网页的示例代码:

include <iostream>
#include <iterator>
#include <vector>

int main() 
{
    std::vector<int> v{ 3, 1, 4 };

    auto distance = std::distance(v.begin(), v.end());

    std::cout << distance << '\n';
}