有没有办法在多映射内联中查找键的数量?

Is There a way to Find the Number of Keys in a multimap Inline?

A multimapsize 报告它包含的值的数量。我对它包含的键数感兴趣。例如,给定 multimap<int, double> foo 我希望能够这样做:

const auto keyCount = ???

实现此目的的一种方法是在零初始化 keyCount:

上使用 for 循环
for(auto it = cbegin(foo); foo != cend(foo); it = foo.upper_bound(foo->first)) ++keyCount;

但是,这不允许我执行内联操作。所以我无法初始化 const auto keyCount.

解决方案可以是包装此 for 循环的 lambda 或函数,例如:

template <typename Key, typename Value>
size_t getKeyCount(const multimap<Key, Value>& arg) {
    size_t result = 0U;

    for(auto it = cbegin(foo); foo != cend(foo); it = foo.upper_bound(foo->first)) ++result;
    return result;
}

但我希望标准提供一些东西。有这种东西吗?

不,标准中没有内置的功能。考虑到您的 count 函数有效,因为 multimap 是内部排序的。 libstdc++ 等典型实现使用红黑树作为内部表示。您需要遍历树才能计算所有(唯一)键。这是不可避免的。

1st, multimap doesn't contain a key count naively. So your question then is about how to use something from the algorithm library 求计数。您设置的 2 个排除库中所有内容的约束是:

  1. 必须内联使用,因此必须返回计数,而不是迭代器
  2. 必须至少与在具有时间复杂度的 lambda 中使用的 upper_bound 一样好:O(log n)

1 给我们留下:countcount_iffor_each,以及 [=23] 中的大多数算法=]

2 消除了对所有这些的考虑,因为它们每个都有时间复杂度:O(n)

因此,您的 getKeyCount 优于标准提供的任何其他选项。


只是对可能出现的另一个选项的评论:每当从 foo 添加或删除某些内容时维护 keyCount,这似乎可行,但它需要在每次插入之前进行检查如果插入的密钥存在,并在每次删除后检查删除的密钥是否仍然存在。除此之外,还有考虑到多线程无法运行的危险和代码可读性的损失,这里不清楚这个keyCount必须和foo一起维护。最终这是一个坏主意,除非密钥计数的使用频率明显高于 foo 的更新频率。

如果您只是创建多映射并在其中插入值,则可以保留一个伴随映射来记录不同类型的键。该地图的大小将为您提供关键数量。