- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
考虑以下代码:
unordered_set<T> S = ...;
for (const auto& x : S)
if (...)
S.insert(...);
这是坏的吗?如果我们在 S 中插入一些东西,那么迭代器可能会失效(由于重新散列),这将破坏范围,因为在引擎盖下它使用的是 S.begin ... S.end。
有什么模式可以解决这个问题吗?
一种方法是:
unordered_set<T> S = ...;
vector<T> S2;
for (const auto& x : S)
if (...)
S2.emplace_back(...);
for (auto& x : S2)
S.insert(move(x));
这看起来很笨重。我错过了更好的方法吗?
(特别是如果我使用的是手动哈希表,并且我可以阻止它重新哈希直到循环结束,那么使用第一个版本是安全的。)
更新:
来自 http://en.cppreference.com/w/cpp/container/unordered_map/insert
If rehashing occurs due to the insertion, all iterators are invalidated. Otherwise iterators are not affected. References are not invalidated. Rehashing occurs only if the new number of elements is higher than
max_load_factor() * bucket_count()
.
您能以某种方式弄乱 max_load_factor
以防止重新散列吗?
最佳答案
Could you mess with max_load_factor somehow to prevent rehashing?
是的,您可以将 max_load_factor()
设置为无穷大,以确保不会发生重新散列:
#include <iostream>
#include <limits>
#include <unordered_set>
int main()
{
// initialize
std::unordered_set<int> S;
for (int i = 0; i < 8; ++i)
S.insert(i);
std::cout << "buckets: " << S.bucket_count() << std::endl;
// infinite max load factor => never need to rehash
const auto oldLoadFactor = S.max_load_factor();
S.max_load_factor(std::numeric_limits<float>::infinity());
for (const auto& x : S)
{
if (x > 2)
S.insert(x * 2);
}
// restore load factor, verify same bucket count
S.max_load_factor(oldLoadFactor);
std::cout << "buckets: " << S.bucket_count() << std::endl;
// now force rehash
S.rehash(0);
std::cout << "buckets: " << S.bucket_count() << std::endl;
}
请注意,简单地设置一个新的负载因子不会重新散列,所以这些操作很便宜。
rehash(0)
位有效,因为它要求:1) 我至少获得 n 个存储桶,2) 我有足够的存储桶来满足我的 max_load_factor()
。我们只是使用零来表示我们不关心最小数量,我们只是想重新哈希以满足我们的"new"因素,就好像它从未更改为无穷大一样。
当然,这不是异常安全的;如果在对 max_load_factor()
的调用之间出现任何问题,我们的旧因子将永远丢失。使用您最喜欢的范围保护实用程序或实用程序类轻松修复。
请注意,如果您将迭代新元素,则无法保证。您将迭代现有元素,但您可能会也可能不会迭代新元素。如果没问题(根据我们的聊天应该是这样),那么这将起作用。
例如,假设您对一组无序整数进行迭代,并为每个偶数 x
插入 x * 2
。如果那些总是在您当前位置之后插入(通过实现细节和容器状态的机会),您将永远不会终止循环,除非通过异常。
如果您确实需要一些保证,则需要使用备用存储解决方案。
关于c++ - 同时迭代和修改 unordered_set?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13981886/
我想创建一个容器来存储唯一的整数集。 我想创建类似的东西 std::unordered_set> 但是 g++ 不允许我这样做并说: invalid use of incomplete type 's
我是 C++ 的新手,被要求将 Java 程序转换为 C++。我正在尝试编写一种方法来检查一个 unordered_set 中的所有元素是否存在于另一个 unordered_set 中。我发现下面的示
我想为我正在编写的类创建一个散列函数,我想让散列函数成为类的 friend ,这样我就不必编写不必要的 getter 方法。为此,我遵循了 this SO post 中接受的答案.但我希望能够将对象插
我想使用 std::pmr::unordered_map与 std::pmr::monotonic_buffer_resource .两者配合得很好,因为集合的节点是稳定的,所以我不会通过重新分配在缓
我有一个每帧创建的项目列表,需要对其进行排序。每个 Item 的第一个排序依据的成员变量是 unordered_set。 我已将其移动到系统中各处的有序集合中,以便我可以在项目列表中对其进行排序。但是
是否有将 std::unordered_set 与实现 operator== 和 hash 的类一起使用的捷径?具体来说,有没有一种方法可以 (1) 避免创建独立的 operator==(const
我正在将 C 文件转换为 C++。由于这些函数仍会从 C 代码中调用,因此我会将整个文件放在 extern "C" block 中。该文件包含以下代码- struct node{ char*
我有一个关于在 unordered_set 中插入的问题。我想建立一个最坏情况插入的例子。我有 30000 个字符串(len string my_set; 关于c++ - Unordered_set
我已经从 C 转向 C++,并且最近学习了 STL。 最后一行在 STL 样式中给出了很长的错误(无助)或者也许我是模板的新手,这就是为什么我觉得它无能为力。 int insert(Forest *f
我正在使用 unordered_set 来实现哈希表。我不知道如何使用查找功能。运行此代码时,我不断遇到段错误。我知道这是因为 find() 没有找到元素,但它应该找到。我的问题是如何通过我提供的自定
这个问题在这里已经有了答案: C++11 initializer list fails - but only on lists of length 2 (2 个答案) 关闭 8 年前。 当我使用包含
这个问题在这里已经有了答案: Subtracting map iterators (2 个答案) 关闭 5 年前。 尝试在无序集中查找元素的索引。发现迭代器的减法(运算符“-”)是一种方法。 vec
我注意到当我使用无序集时 unordered_set theSet;为了保存大量整数,即使调用 clear() 或 rehash(0),它也不会释放内存。即使我在函数中本地定义了集合,并且函数完成执行
谁能解释一下无序集是如何工作的?我也不确定一套是如何工作的。我的主要问题是它的查找功能的效率如何。 例如,这个大 O 的总运行时间是多少? vector theFirst; vecto
我一直在阅读 cplusplus.com 网站并尝试确保我的 unordered_set 号码不会以任何方式被修改。该站点表示容器的元素未排序,普通 set 就是这种情况。 该网站还说: Intern
我有: std::unordered_set _buttons; std::unordered_set _sprites; std::unordered_set _someOtherSprites;
缩小范围:我目前正在使用 Boost.Unordered .我看到两种可能的解决方案: 定义我自己的Equality Predicates and Hash Functions并利用模板(可能是 is
我有一个类需要一个 std::unordered_set它持有不可复制、不可移动的实体对象,并且其哈希函数对实例的地址进行哈希处理。类似于以下内容: class A { public: A()
我正在尝试散列一个 Edge 结构,以便我可以拥有一个具有唯一边的 unordered_set。在我的例子中,如果一条边的两个端点的组合在之前的集合中没有遇到,则该边被认为是唯一的。 虽然我的代码适用
我已经成功地为自定义类创建了一个散列函数(和 == 覆盖),因此我可以在 unordered_set 中使用它。但是,理想情况下,我想在要使用的类附近为我的类定义模板特化。这可以通过以下方式完成,效果
我是一名优秀的程序员,十分优秀!