【问题标题】:C++ how does std::set handle dynamic ordering of elementsC++ std::set 如何处理元素的动态排序
【发布时间】:2013-10-01 19:54:36
【问题描述】:

我有一个用我自己的 comp 函数声明的集合:

set<int, my_comp> my_set;

比较函数使用存储在别处的一些数据来决定哪个 int 更大。 如果所述数据发生变化,则集合元素的顺序也会发生变化。

set 如何处理这个问题? 如果我知道一个 int 的相对位置可能已经改变,我是否必须移除并重新插入它?

详细信息:特别是,my_comp 使用整数作为索引来访问向量并比较向量中包含的值。上述值必然会发生变化。

【问题讨论】:

  • 没有简单的解决方案。据std::set 所知,即使是对订单的最小更改也可能会迫使树重新平衡到根节点。自定义红黑树可能会通过不回收旧节点的内存来节省一些时间,但仅此而已。

标签: c++ set stdset


【解决方案1】:

不,std::set 中的元素的严格弱顺序不得更改,键必须视为const

比较函数必须是strict weak ordering的模型:

严格的弱排序具有以下属性。对于所有 xyz 在 S 中,

  • 对于所有 xx x(非自反性)并非如此。
  • 对于所有xy,如果xy那么情况不是y x(不对称)。
  • 对于所有 xy 和 z,如果 x y 和 y z 然后 x z(传递性)。
  • 对于所有 xyz,如果 xy,而yz不可比,则xz不可比 (不可比性的传递性)。

更好的解决方案可能是排序的std::vector,以及std::sort(对其进行排序)、std::lower_bound(用于查找和插入元素)、std::inplace_merge(用于插入元素)。

【讨论】:

  • 我猜比较功能只在插入和删除元素时使用。因此,我是否仍然可以使用集合,但通过移除并重新插入来手动重新定位元素?
  • 使用矢量我将有线性时间来重新定位元素。我需要集合的对数成本。
  • 我们所说的元素有多少? std::vector&lt;int&gt; 中元素的重定位并没有那么慢。
  • @user2460978:我必须检查以 100% 确定,但我相信其他操作也可能需要它。作为一个明显的例子,在集合中定位元素。
  • @dalle: 100 到 300。但这是一个非常关键的操作。
猜你喜欢
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
相关资源
最近更新 更多