我想在少于O(N)的时间内计算std::multimap
的两个迭代器之间的条目数。是否有任何技巧或巧妙的方法来做到这一点?
由于std::multimap
具有双向迭代器,我的理解是像std::distance
这样的东西可以在O(N)时间内完成。
其他详细信息:multimap
的密钥是N元组。我正在尝试找到multimap
中键的第一个元素为0的条目数。它们键的第一个元素的选项是0和1,而multimap
使用严格的弱排序其中键的第一个元素始终是最重要的。即所有带0的元素都来自任何带有1的元素。
上下文:迭代器由equal_range
返回,它以对数时间运行。据说,我想测量范围的长度。
谢谢。
答案 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';
}