【问题标题】:What is the most efficient way to retrieve a line from a file containing multiple sorted runs从包含多个排序运行的文件中检索行的最有效方法是什么
【发布时间】:2014-11-05 23:50:33
【问题描述】:

正如标题所暗示的,我有一个包含按 A-Z 排序的词汇表(每个在一行上)的文件,我想检索具有给定前缀的所有词汇表。 问题在于该文件包含多个 A-Z 排序运行,每个运行代表不同的语言。对数据文件进行预处理是不可能的,因为您无法确定排序运行的长度,所以我想不出比简单地遍历整个文件并比较需要 O(n) 的运行更好的方法。用这个奇怪的排序文件有可能实现 O(logN) 吗?

【问题讨论】:

  • 你能确定一个排序运行的最小长度吗?如果可以,那么您可以使用它来跳过以识别已排序的运行,而无需查看大多数行。
  • @btilly 我不能假设任何事情,因为我所拥有的只是一个数据文件,设计应该容忍任何事情。
  • 你能数出每行的字符数吗? (每个字典的字面长度)

标签: algorithm sorting search full-text-search


【解决方案1】:

如果在运行大小未知时既不允许索引也不允许更改文件,没有什么比全文件扫描更好的了。

但是,如果每次运行的开始-结束偏移量已知,则只需要进行一次完整文件扫描,并且可以在每个部分中使用二进制搜索 - 在索引构建后查找 ~O(k lg (n/k))。起始偏移量在程序运行期间很容易获得,并且可以根据需要存储在缓存文件中。

如果首尾索引也包含相关的顶级前缀,如起始字母,那么可以进一步划分初始搜索空间,避免几次搜索。

如果文件很小,并且内存足够,也可以选择将所有内容保存在内存结构中。可能也值得研究一下现有的商店,比如 SQLite;虽然据说预处理是不可行的。

【讨论】:

  • 文件很大,所以内存中排序不是一个选项。是的,有偏移量会很好,但不幸的是我没有准备好。也许全面扫描是不可避免的。
  • @r0dney 全扫描只需要进行一次,所以如果在同一个进程中多次查询(或创建缓存/索引文件),那么它肯定会得到回报。
  • 我也想过同样的事情,但一直想知道是否有更好的解决方案。
  • @r0dney:这是最好的解决方案。索引摇滚。 (您可以拥有多少种语言?当然,起始位置列表将是微不足道的空间。)
【解决方案2】:

您可以将 k 个列表合并为 1 个排序列表(k 路合并),这是一个一次性的 o(n*lg(k)) 任务。之后你就可以在 o(log n) 中运行了。

【讨论】:

    猜你喜欢
    • 2016-11-01
    • 2010-11-07
    • 1970-01-01
    • 2011-07-23
    • 2014-02-03
    • 2011-02-03
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    相关资源
    最近更新 更多