最好保存大量名称的 C++ 数据结构

Posted

技术标签:

【中文标题】最好保存大量名称的 C++ 数据结构【英文标题】:C++ Data Structure that would be best to hold a large list of names 【发布时间】:2014-10-01 01:53:53 【问题描述】:

您能否分享您对存储大量名称并在这些名称上执行搜索的最佳 STL 数据结构的看法?

编辑: 名称不是唯一的,并且列表可以随着不断添加新名称而增长。总的来说,我指的是 100 万到 1000 万个名字。

【问题讨论】:

名称是否唯一?您是创建此容器一次然后搜索多次,还是有一些添加/删除项目以及搜索?是否需要按字母顺序遍历容器? 动态数组或 std::vector(物理上相同)。 set和链表不适合大量元素,因为添加时间太长。 另外,多大是多大?如果只有几百万个长度为 10 个字符的名称,则 std::map 在配置合理的笔记本电脑上可能没问题。如果您需要数十亿个名称,每个名称都有 100 个字符长,或者如果您有一个内存受限的系统,您可能需要一个核外解决方案,这可能会排除 STL(尽管 Google 找到了 stxxl.sourceforge.net,它声称处理这种情况)。 提升享元库boost.org/doc/libs/1_56_0/libs/flyweight/doc/index.html 【参考方案1】:

由于您要搜索名称,因此您需要一个支持快速随机访问的结构。这意味着向量、双端队列和列表都不存在。此外,向量/数组对有序集合的随机添加/插入很慢,因为它们必须移动项目以为每个插入的项目腾出空间。不过,添加到结尾非常快。

考虑std::mapstd::unordered_mapstd::unordered_multimap(或它们的兄弟std::setstd::unordered_setstd::unordered_multiset,如果您只存储密钥)。

如果您纯粹是要进行唯一的随机访问,我会从 unordered_* 容器之一开始。

如果您需要存储名称的有序列表,并且需要进行范围搜索/迭代和排序操作,那么像 std::mapstd::set 这样的基于树的容器在迭代操作方面应该比基于哈希的容器做得更好因为前者将存储与其逻辑前任和继任者相邻的项目。对于随机访问,O(log N) 仍然不错。

在 std::unordered_* 之前,我使用 std::map 为对象缓存保存大量对象,尽管有更快的随机访问容器,但它的扩展性足以满足我们的使用需求。较新的 unordered_map 的访问时间为 O(1),因此它是一个散列结构,应该为您提供近乎最佳的访问时间。

【讨论】:

如果他只有一个字符串列表而没有将它们映射到的东西,那么各种set 容器是更好的选择。 但是他要把名字映射到什么地方呢? 我不确定他是否需要存储记录,或者名称是否就是记录。我确信他可以根据需要替换相应的设置选项。无论如何,如果您觉得我引用 set* 兄弟姐妹会改进答案,我会编辑它。 除非问题得到改善或您喜欢写书,否则我认为这是您将要做的最好的事情。 :)【参考方案2】:

您可以考虑使用分隔符连接这些名称的可能性,但搜索可能会受到影响。您需要提出调整后的二进制搜索。

但是您应该首先尝试显而易见的解决方案,即在 stl 中称为 unordered_map 的 hashmap。看看是否满足您的需求。那里的搜索速度应该很快,但会消耗内存。

【讨论】:

以上是关于最好保存大量名称的 C++ 数据结构的主要内容,如果未能解决你的问题,请参考以下文章

当数据不是静态的时,我应该如何保存大量数据。 iOS、可可触控、Obj-C

带有 fstream 或数据库的 C++

数据库savepoint

C++下如何将json数据存入mysql数据库

将文件保存到 C++ 中用户输入定义的位置和名称

Apache Spark 和 Hudi:大量的输出文件