Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 哪个STL容器?_C++_List_Stl_Containers - Fatal编程技术网

C++ 哪个STL容器?

C++ 哪个STL容器?,c++,list,stl,containers,C++,List,Stl,Containers,我需要一个容器(不一定是STL容器),它可以让我轻松地执行以下操作: 在任何位置插入和移除元件 通过索引访问元素 按任意顺序迭代元素 我使用了std::list,但它不允许我在任何位置插入(它允许,但为此我必须迭代所有元素,然后在我想要的位置插入,这很慢,因为列表可能很大)。那么,你能推荐一些有效的解决方案吗?很遗憾,你不能在固定的时间内拥有所有这些解决方案。决定是否要进行更多的插入或读取,并以此为基础做出决定 例如,a允许您在固定时间内通过索引访问任何元素,在线性时间内迭代元素(所有容器都

我需要一个容器(不一定是STL容器),它可以让我轻松地执行以下操作:

  • 在任何位置插入和移除元件
  • 通过索引访问元素
  • 按任意顺序迭代元素

我使用了std::list,但它不允许我在任何位置插入(它允许,但为此我必须迭代所有元素,然后在我想要的位置插入,这很慢,因为列表可能很大)。那么,你能推荐一些有效的解决方案吗?

很遗憾,你不能在固定的时间内拥有所有这些解决方案。决定是否要进行更多的插入或读取,并以此为基础做出决定


例如,a允许您在固定时间内通过索引访问任何元素,在线性时间内迭代元素(所有容器都应该允许),但插入和删除需要线性时间(比列表慢)。

我不完全清楚“以任何顺序迭代元素”是什么意思-这是否意味着您不关心顺序,只要您可以迭代,或者您希望能够使用任意定义的条件进行迭代?这是非常不同的条件

假设您的意思是迭代顺序无关紧要,那么会想到几个可能的容器:

std::map
[通常为红黑树]

  • 插入、删除和访问是O(log(n))
  • 迭代按索引排序
hash_-map
std::tr1::无序_-map
[哈希表]

  • 插入、移除和访问都是(大约)O(1)
  • 迭代是“随机的”

矢量
或德克
都适合
vector
将提供更快的访问速度,但deque
将提供更快的插入和删除速度。

您可以尝试,但它不会提供中间元素的固定时间删除,但它支持

  • 元素的随机访问
  • 恒定时间插入和移除 项目末尾的元素数 序列
  • 线性时间插入和删除 元素在中间。
std::vector


[在这里填充“15个字符]

会对你有很大帮助,我想是的。

向量。擦除任何项目时,将最后一个项目复制到要擦除的项目上(或交换它们,以速度较快的为准),然后弹回来。若要在某个位置插入(但如果顺序不重要,为什么要这样做呢?),请将该位置的项向后推,并用要插入的项覆盖(或交换)。

通过“按任何顺序迭代元素”,您的意思是需要支持按索引向前和向后,还是说顺序不重要

您需要一个称为未排序计数树的特殊树。这允许O(log(n))索引插入、O(log(n))索引删除和O(log(n))索引查找。它还允许在正向或反向进行O(n)迭代。文本编辑器就是一个例子,编辑器中的每一行文本都是一个节点

以下是一些参考资料:


订单统计树在这里可能很有用。它基本上只是一个普通的树,除了树中的每个节点都包含其左子树中的节点数。这支持所有基本操作,其复杂度不低于对数。在插入过程中,无论何时在左子树中插入项,都会增加节点的计数。在删除过程中,无论何时从左子树中删除,都会减少节点的计数。要索引到节点N,请从根开始。根在其左子树中有一个节点计数,因此可以检查N是否小于、等于或大于根的计数。如果较少,则以相同的方式在左子树中搜索。如果大于,则从右子树向下,将根的计数添加到该节点的计数中,并将其与N进行比较。继续,直到A)找到正确的节点,或B)确定树中的项目少于N项。


(来源:)

但听起来您正在寻找具有以下属性的单个容器:

  • 各种容器的所有最佳优点
  • 没有任何随之而来的负面影响

这是不可能的。一利则弊。选择一个容器就是妥协。

你想解决什么问题?我的意思是,只要我能从开头/结尾得到一个迭代器,然后使用该迭代器迭代所有元素+1非常巧妙的答案::-)我想说的是它不提供索引访问,但是如果你使用索引作为键,这实际上是可行的,而且是合理的…尽管除了在末尾之外,移除后索引不会是连续的。只有在末尾(和开始?)。否则,它们都是相同的,无向量将所有内容存储在一个块中,因此访问速度非常快,但随机插入和删除速度很慢。deque存储为多个连接块,因此访问速度比vector慢,但随机插入和删除速度比vector快。开始和结束时的插入对于无失真缓冲区的重新分配和元素的相应移动来说速度更快。@sharptooth:从中间到结束的失真插入比向量快一点。它只是在开始的时候快得多。插入中间?你是初学者吗?你认为std::vector不支持这种插入吗?不,但我读了这个问题。他已经抱怨说,仅仅在
std::list
中迭代到正确的位置太慢了。这需要O(N)个指针解引用。插入<<代码> STD::vector 需要复制O(n)元素。这可能是更昂贵的。几乎每个人都知道向量::插入()是非常昂贵的,但是你考虑处理器缓存吗?std::list和std::map导致缓存未命中,访问内存非常昂贵(例如,访问一级缓存的成本:3个周期,但