我有一个unordered_set如下:
unordered_set <long> valueSet;
/*the following insertion is done in order (from 1 to 10000),
*unordered_set will keep the elements based on the insertion order, right,
*just like in a vector ?
**/
for(long i = 1; i <= 10000;++i)
{
valueSet->insert(i);
}
然后我执行了另一个功能,它删除了那个unordered_set中大约85%的元素。 (要删除的元素取决于此函数的逻辑,但它并不重要,因为所有元素最初都是按顺序插入的。)
现在在删除了unordered_set中的一些元素后,我想打印仍然保留在unordered_set中的最后一个元素。例如,元素9997,9998,9999和10000已被擦除,因此该组中剩余的最大元素是9996。
怎么做?
如果使用基本集,我可以执行以下操作:
set <long>::reverse_iterator it = valueSet.rbegin();
cout << *it << endl;
在一个集合中,我们有reverse_iterator和rbegin(),但是在unordered_set中不存在。我没有基本集的原因是我需要元素大小扩展到10 ^ 8。使用常规集(基于红黑树)将确实杀死性能(特别是当它处理插入和删除时)。 我怎样才能做到这一点?将最终剩余的unordered_set复制到向量将起作用,但当然这需要时间。如何通过更智能的方式实现这一目标?我注意到我也做不了类似的事情:
unordered_set <long>::iterator it = valueSet.end();
//operator -- does not exist here in the unordered_set
it--;
答案 0 :(得分:1)
无序集合旨在无序。你应该假设你在使用它的迭代器时看到它的元素的顺序是任意的/不确定的。这意味着有关订单的任何特定行为从定义上讲是不可移植的,并且完全针对具体实它现在可能正好按顺序排列,但经过足够的操作之后,它可能会处于另一个顺序。他们给你一个迭代器的唯一原因是允许你以任意顺序逐个元素地处理它。
为什么不从头开始使用std :: vector?
答案 1 :(得分:1)
根据我从您的评论中收集到的内容,使用std::bitset或其动态对应boost::dynamic_bitset应该适当。您获得O(1)插入和删除以及O(N)以确定最大元素(通过线性搜索)。甚至可以争辩说找到最大值是分摊O(1),因为你必须做的最多的搜索步骤与删除操作一样多。
答案 2 :(得分:1)
你不能吃蛋糕并且吃它。
无序容器以无序方式存储它们的元素(通常在hash table内),因此您无法以可预测的方式迭代它们。特别是,它们不会按插入顺序存储元素。
如果您不关心订单,那么您最好使用std::deque
或std::vector
(如果您必须在前面插入,则更喜欢前者)。
答案 3 :(得分:0)
将已删除的项目存储在矢量中。完成后,转换为堆。 (O(n),其中n是已删除项目的数量)然后重复从堆中删除最大值,直到找到未删除的最高元素。那是O(m log n),其中m是你的最大值和答案之间的差异。