我一直在使用C ++ STL,但从未真正使用多重集(或多图)。我有一个基于计算具有相同键的元素数量的问题。例如。 这是一个unordered_multiset {0,2,5,1,1,2,7,5}
如果我说,count(5),它应该返回2.有两种方法可以使用unordered_multiset的C ++ 11标准来实现。 1)count 2)equal_range然后减去生成的迭代器。
据说1)在出现次数上采用线性时间,但2)是恒定时间。那是为什么?
答案 0 :(得分:3)
首先,equal_range的复杂性记录在您自己提供的链接中:
Average case: constant.
Worst case: linear in container size.
其次,“减去生成的迭代器”的逻辑操作必须使用复杂度为O(bucket_size(bucket(key)))
的线性迭代来实现,逐步执行哈希冲突值的列表或向量检查比赛,所以......
"2) equal_range and then subtracting the resulting iterator"..."is constant time"
......不是一个有根据的断言。
对于“1)计数”,在这种情况下同样记录复杂性:
Average case: linear in the number of elements counted.
Worst case: linear in container size.
可能与“出现次数的线性时间”不同。 平均值的原因通常是max_load_factor
默认值为1.0且散列函数很好,只会出现随机散射的碰撞 - 大约10-20%标记,因此 键散列到特定存储桶的大多数将是您正在计算的那些 - 平均值是1.1x或1.2x左右的常数倍那 - 因此是线性的。
答案 1 :(得分:2)
问题是equal_range返回"转发迭代器" (这在您提供的链接中提到),与随机访问迭代器相比,它只定义了增量操作。因此,为了计算两者之间的差异,我们必须增加第一个,直到它变得等于第二个 - 这给出了线性计数时间。
例如,在gcc中,标准库计数以这种方式实现:
count(const _Key& __k) const
{
pair<const_iterator, const_iterator> __p = equal_range(__k);
const size_type __n = std::distance(__p.first, __p.second);
return __n;
}
答案 2 :(得分:1)
Ex:mymultiset.count(73)
对数大小:要找到与二元搜索相同的元素
匹配数量的线性:由于找到了元素,它将线性流动以了解匹配的数量,因为我们知道集合已经排序
&#34;该函数返回一对,其成员对:: first是范围的下限(与lower_bound相同),而pair :: second是上限(与upper_bound相同)。 &#34;
检查最低复杂度以获得上限/下限你会发现它(对数大小) 您也可以检查该链接:http://www.cplusplus.com/reference/set/multiset/equal_range/