【发布时间】:2018-09-22 18:52:53
【问题描述】:
假设我有一个std::set(根据定义已排序),并且我有另一个已排序 元素范围(为简单起见,在不同的std::set 对象中)。另外,我保证第二组中的所有值都大于第一组中的所有值。
我知道我可以有效地将一个元素插入std::set - 如果我传递一个正确的hint,这将是O(1)。我知道我可以将任何范围插入std::set,但由于没有传递hint,这将是 O(k logN)(其中 k 是新元素的数量,N 是旧元素的数量元素)。
我可以在std::set 中插入一个范围并提供一个hint 吗? 我能想到的唯一方法是使用hint 进行k 次插入,这确实推动了在我的例子中,插入操作的复杂性降至 O(k):
std::set <int> bigSet{1,2,5,7,10,15,18};
std::set <int> biggerSet{50,60,70};
for(auto bigElem : biggerSet)
bigSet.insert(bigSet.end(), bigElem);
【问题讨论】:
-
为什么 k 暗示插入复杂度 O(1) 会导致 O(kN) 复杂度操作?不是 O(k) -pun 不是故意的吗?
-
@papagaga 哦,好吧,那是因为
k乘以1等于kN以获得足够大的1值:) 抱歉,错字,我把它编辑掉了。 -
我想知道
std::set是不是您要找的东西。使用它来保持排序的集合不是一个好主意。当您需要依赖插入不会使迭代器和引用无效的属性时,您可以使用std::set。为了保持排序的集合,std::vector和<algorithm>通常是最好的选择。而你所要求的就是两个vectors -
@papagaga 我实际上正在使用
std::maps,它在某种程度上代表了非常稀疏的直方图。我计算了其中几个直方图(大约 10 个,而不是数千个)。计算很复杂,我需要添加和更新很多很多元素,所以我需要查找/插入 O(logN) 并且std::map是正确的数据结构。每次计算后,我需要通过添加当前直方图的信息来更新“全局直方图”,这就是我的问题所指的。为了简单起见,我用std::set提出了这个问题。 -
@papagaga 目前我的构造是 O(NlogN)。使用向量,我需要在每次插入之前至少 std::find 检查重复项(80% 以上的插入是重复项;所以保持所有内容然后过滤唯一是可怕的记忆方式),并将其排序结束 - O(N^2 + NlogN)。每次我需要从稀疏直方图中读取一个值时,我还需要 std::find ,这又不是很理想。