【问题标题】:Efficient string searching in JavaJava中的高效字符串搜索
【发布时间】:2018-05-22 11:12:09
【问题描述】:

我正在处理两个大数据列表,我需要有效地检查两者之间的匹配。这是场景:

  • 逐行读取文件(该文件有100万行)
  • 对于每一行,检查一个 ArrayList 中的字符串是否匹配(这个 ArrayList 也有大量元素)
  • 如果找到匹配项,则将文件中的行替换为新值

任何想法在效率方面解决这个问题的好方法是什么?显然,循环遍历这么多记录的效率极低且处理繁重。

感谢您的帮助!

更新 值得注意的是,我并不是说我需要 使用 ArrayList,这只是我用于测试的东西。欢迎任何关于更高效收藏的建议。

【问题讨论】:

  • 不是重复的或任何东西,但this answer 可能会有所帮助
  • 为什么要使用 ArrayList 来检查匹配项?改用 HashSet 不是更好吗?
  • 在您的上下文中“匹配”是什么意思? fileLine.equals(collectionElement) ?
  • 正如 Ralf Renz 所说,使用 hashMap 作为第二个列表。然后将是 O(N) 时间检查所有匹配项。此外,如果第一个列表是一个集合(没有重复值),那么您可以删除 hashMap 中已经匹配的值。我还假设您没有检查新值的匹配项,是吗?
  • 这取决于您是否可以将行解析为单词,或者您想要支持任何字符串的通用方法(不一定受单词边界的限制)。第一个最好使用单词索引(Bloomfilter、Hashmap、Trie),第二个使用多字符串匹配算法(例如 Aho-Corasick)。

标签: java string performance search processing-efficiency


【解决方案1】:

如果没有更多详细信息(例如键的性质),很难确定,但您可能会发现使用 Bloom filter 有助于最大限度地减少您使用 check within an ArrayList of strings whether it has a match 的次数。

如果查找列表随时间变化,这显然不会有太大帮助。

您可以在搜索列表之前使用 Bloom 过滤器进行预检查,因为如果列表中不存在该键,它可以非常快速地为您提供直接的 no 答案。如果布隆过滤器显示maybe,您仍然需要搜索您的列表。

【讨论】:

    【解决方案2】:

    您可以考虑通过不同的线程部分读取文件。 here 讨论了类似的问题。

    您可以分块处理文本(比如 x 个字节或一行),每个块可以由不同的线程执行,即每个块一个线程。

    【讨论】:

    • 参考指向读取大文件而不是在大文件中搜索。
    【解决方案3】:

    你应该使用 HashMap,它大约是 O(1),或者如果你的字符串有很多冲突而不是你需要使用 TreeSet O(logN) 或 Bloom 过滤器。

    【讨论】:

    • HashSet 将桶组织为树,如果自 Java 8 以来存在许多冲突
    • 是的,但是只有 TreeSet 会比 HashMap+TreeSet 快。
    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多