【问题标题】:Dynamic size of array in c++?c++中数组的动态大小?
【发布时间】:2011-10-24 16:36:46
【问题描述】:

我很困惑。我不知道我应该使用什么容器。我先告诉你我需要什么。基本上我需要一个可以存储 X 个对象的容器(对象的数量是未知的,可能是 1 - 50k)。

我读了很多,在这里array vs list 它说:如果对象的数量未知,则需要调整数组的大小(我不确定如何在 C++ 中调整数组的大小),它还指出,如果使用链表,如果要搜索某个项目,它将从头到尾循环(迭代)(反之亦然),而数组可以指定“索引处的数组对象”。

然后我选择了另一种解决方案,地图、矢量等。就像这个:array vs vector。一些响应者说永远不要使用数组。

我是 C++ 新手,之前只使用过数组、向量、列表和映射。现在,就我而言,您会推荐我使用哪种容器?让我重新表述一下我的要求:

  • 需要是容器
  • 存储的对象数量未知,但很大(可能 1 - 40k)
  • 我需要遍历容器以查找特定对象

【问题讨论】:

  • 您可能想阅读一些书籍,其中包含有关数据结构的章节,以了解为什么您会选择其中一种。 编辑: Als 的图表涵盖了我的其余评论 :)
  • 当您说遍历容器以查找特定对象时,您的实际意思是什么?在给定位置定位元素?找到一个你知道值的元素?找到满足某些条件的元素?
  • @david:当新的输入/字符串进来时,我需要检查它是否存在于我的容器中,如果不存在则我创建一个新的。

标签: c++ arrays list vector containers


【解决方案1】:

一般规则是:使用std::vector 直到它不起作用,然后切换到起作用的东西。关于哪个更好,取决于操作,有各种各样的理论规则,但我经常发现std::vector 优于其他操作,即使最频繁的操作是std::vector 被认为更糟的事情。局部性似乎比现代机器上的大多数理论考虑更重要。

您可能从 std::vector 转移的一个原因是迭代器有效性。插入std::vector 可能会使迭代器无效;从不插入std::list

【讨论】:

  • 从向量转换到列表是否需要很多时间(编码方面),因为我仍然不熟悉这 2 个(但我以前使用过一次,但是,我不记得它们很多)
  • 这取决于你用它们做什么。如果你做任何使用随机访问的事情,那么转移到列表将很困难。否则,只需更改类型就足够了。
【解决方案2】:

std::vector 是您所需要的。
选择 stl 容器时必须考虑两件事。

  1. 您要存储的数据
  2. 要对存储的数据执行的操作

在 SO 上的一个问题中有一个很好的图表,它描述了这个,我找不到它的链接,但我很久以前就保存了它,这里是:

【讨论】:

  • 不错的图表,但它缺少一个警告:few 个对象? --> vector.
  • +1;这张图的唯一问题是它需要附有关于每个框的段落到一章:) 非常适合参考,但不适合学习。
  • 嘿伙计。这是很棒的图表(我也保存了图表)。非常感谢:D
  • 实际上,这是一个非常糟糕的图表,因为它忽略了一个主要问题(迭代器的有效性)并做出了一些不合理的假设:需要在中间插入立即导致list,但是@ 987654325@也支持中间插入,即使插入中间一般也比list好。
  • 我同意 James 的观点,即图表和问题中缺少一些内容。我发现用户接受了这个答案很有趣,在对问题添加了一条重要信息作为评论之后:他想要执行查找以确定容器中是否存在元素!这意味着根据图表,它应该是mapset(并添加缺失的位:或unordered_mapunordered_set)。同样,请注意不完整的问题(缺少重要信息)和答案(可能缺少详细信息)
【解决方案3】:

您可以使用vector。但是如果需要在容器中查找对象,那么可以考虑使用setmultisetmap

【讨论】:

    【解决方案4】:

    您是否需要遍历容器,或者您有对象的键或 ID?

    如果您有键或 ID - 您可以使用 map 以便能够通过它快速访问对象,如果 id 是简单索引 - 那么您可以使用 vector

    否则,您可以遍历任何容器(它们都有迭代器),但如果您想提高内存效率,list 是最好的,如果您想以性能为导向,vector 是最好的。

    【讨论】:

    • "但是如果您想提高内存效率,list 将是最好的选择" --> list 根本没有内存效率,因为每个节点都是独立分配的(祈祷您的 malloc 实现不会在每个节点上浪费太多空间)并且至少在数据顶部包含 2 个指针。 list唯一 优点是 splice 及其迭代器失效规则(后者源于它是基于节点的容器这一事实)。
    • @Matthieu - 是的,你是对的。然而...vector 以先前的倍数增加分配,这意味着在 20K+1 项目上,您最终可能会获得 40K 分配空间。您指的是碎片,这可能是一个问题。我指的是利用率,这也可能是一个问题。 OP 是决定哪个对他更重要的人。
    • @littleadv - 另一方面,在 20k-1 时,您只会浪费向量中的一个元素,但链表中有 40k 指针。
    • @littleadv:实际上,这个因素取决于实现。解决方案是使用std::vector::reserve,它允许您提前分配空间。实现可能会“碰撞”请求的数字(gcc 不会),但如果您的 STL 实现不佳,std::vector 可能是您最后的担忧...
    【解决方案5】:

    您无法在 C++ 中调整数组的大小,不确定您是从哪里得到的。你需要的容器是std::vector。

    【讨论】:

    • 如果你真的想要,你可以,即使手动或使用realloc。不过你不应该。
    • 我在想用T a[n]; 声明的数组(对于一些常数n),你不能调整它们的大小。动态分配的内存块当然可以调整大小(这就是 std::vector 所做的),但我不会称它们为数组。
    • @john:来自我问题中的第一个链接(SO 中的另一个问题)。这就是为什么我说,我不知道该怎么做;p
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2012-04-17
    • 2012-10-02
    • 2014-02-23
    • 2014-11-15
    • 2020-11-13
    相关资源
    最近更新 更多