【问题标题】:Creating maps of maps from a dictionary file in c++从 C++ 中的字典文件创建地图的地图
【发布时间】:2015-08-21 06:56:25
【问题描述】:

我有一个包含单词列表的文本文件(大约 35 MB 的数据)。我写了一个应用程序,它的工作原理很像 Scrabble helper 左右。我发现将整个文件加载到一个集合中是不够的,因为它需要大约 10 分钟才能完成。我在 C++ 方面没有那么丰富的经验,因此我想问你有什么更好的方法来实现它?在我的第一个应用程序版本中,我只是对它进行了二进制搜索。所以我设法通过对文件进行二进制搜索来解决这个问题(不加载它,只是使用 seekg 移动文件指针)。但是这个解决方案不如使用地图地图那么快。搜索单词时,我会在地图中查找它的第一个字母。然后我检索可能的第二个字母的地图,然后我再次搜索(第二个字母)等等。通过这种方式,我能够更快地判断该单词是否在字典中。如何在不将整个文件加载到程序中制作这些地图的情况下实现它?我可以将它们保存在数据库中并阅读它们吗?那会更快吗?

【问题讨论】:

  • 您是在问如何构建这个数据结构而不读取整个文件?我认为这行不通。
  • 看来您正在重新发明文件索引方案...
  • 那么处理庞大字典的应用程序是如何工作的呢?就像,假设我想对 3 或 4 种语言应用相同的逻辑。尝试加载 1000 万个单词时,我可能会耗尽内存。
  • 完全有可能。您只需序列化地图内容并重新加载衍生化数据。只要您不更改文件(或操作系统),seekg 位置就有效
  • 所以你建议将整个结构保存到一个文件中并作为二进制文件加载回来?

标签: c++ performance dictionary


【解决方案1】:

首先,我同意 Ami 的观点,即 35 MB 原则上不应该花那么长时间来加载和存储在内存中。您的加载代码是否有问题(例如意外复制地图,导致大量分配/解除分配)?

如果我理解你的意图,你会构建一种 trie 结构(trienot树)使用您描述的地图。如果在内存中这可能非常好,但是如果您只想将部分地图加载到内存中,那将变得非常困难(从技术上来说不是这样做,而是确定要加载哪些地图,哪些不加载) .尽管有一些persistend tries 的实现,但您可能会从磁盘读取比实际需要更多的数据。

如果您打算在磁盘上使用索引方案,我建议您使用传统的 B-tree 数据结构,该结构旨在优化部分索引的加载。您可以编写自己的,但已经有几个实现(参见this SO question)。

现在您还可以使用 sqlite 之类的东西,这是一个轻量级的 DMS,您可以轻松地将其嵌入到您的应用程序中。

【讨论】:

    【解决方案2】:

    35MB 的数据很小。将其全部加载到内存中没有问题,也没有理由需要 10 分钟才能加载。如果需要这么长时间,我怀疑您的加载方案会重新复制地图。

    但是,与其解决这个问题,或者想出自己的方案,也许您应该尝试一些准备好的东西。

    您的描述听起来像是您可以使用嵌套结构的数据库。具有C++ interfaceMongoDB 是一种可能的解决方案。

    为了提高效率,您可以对该方案进行一些花哨的操作。最多说出 5 个字母的单词,您可以使用 multikey index。除此之外,您还可以使用完全嵌套的结构。

    只是不要自己做。专注于您的程序逻辑。

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 2018-05-01
      • 1970-01-01
      • 2016-03-18
      • 1970-01-01
      • 2017-12-22
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多