【问题标题】:Java: Most efficient way to check if a String is in a wordlistJava:检查字符串是否在单词列表中的最有效方法
【发布时间】:2013-09-10 14:03:34
【问题描述】:

我有一个字符串数组String[] words 和一个 28000 字的单词列表。

我想检查字符串数组的任何成员是否在 WordList 中(单词列表在文本文件 wordlist.txt 中)

最有效的方法是什么?

【问题讨论】:

  • 听起来您使用了错误的数据结构。 HashSet 可能会更好。
  • 这会占用大量内存
  • 用单词列表形成一个kd-tree,每个字母表是一个维度。获取您的 String[] 单词并在树中找到最近的邻居。

标签: java string-comparison


【解决方案1】:

如果您的单词列表可以放入内存,则 HashSet 就足够了。

如果内存大小是一个问题,请使用BloomFilter。虽然布隆过滤器可能会给出错误的答案,但您可以调整它发生的概率。

【讨论】:

    【解决方案2】:

    将字符串直接放入HashSet<String> 而不是数组中,并在集合上使用contains 遍历文件以检查内容。您不会改进 O(1) 访问。如果存在任何重复项,这还将最小化用于存储 Strings 的内存。

    【讨论】:

    • 那么将整个单词表也读入 HashSet 不是一个好主意?
    • 不,您需要删除重复项以减少内存占用,因此直接使用 HashSet 是一种方式(另外,您不必重新填充 HashSet - 在代码使用方面也有微小的优势!)
    【解决方案3】:

    HashSet's add() 如果单词已经存在于集合中,则返回 false。

    for (String str : words) {
      if (!wordSet.add(str)) {
        System.out.println("The word " + str + " is already contained.");
      }
    }
    

    这比contains() 更复杂一点,层次更低。

    【讨论】:

      【解决方案4】:

      存储一个序列化的 HashSet,而不是原始 words.txt。作为运行应用程序的单独步骤。

      然后应用程序只需要加载哈希集一次。

      【讨论】:

        【解决方案5】:

        创建一个HashSet 的字符串为

        HashSet<String> wordSet = new HashSet<String>(Arrays.asList(words));
        

        然后使用HashSet.contains(Object o) 方法在HashSet 中检查word,其中word 是您要检查的单词是否存在。

        【讨论】:

          【解决方案6】:

          Step1:不要使用字符串数组。而不是使用 HashSet。

          Step2:将文件(即wordlist.txt)内容加载到另一个HashSet中

          第三步:

          Set<String> set1 = new HashSet<String>(); //Load the string array into set
              Set<String> set2 = new HashSet<String>(); //load the file contents into set
              for (String str : set1) {
                  for (String str2 : set2) {
                      if (str.equalsIgnoreCase(str2)) {
                          break;
                      }
                  }
              }
          

          【讨论】:

          • 检查 set2.contains(str) 会更快。这是 1 阶操作,也是使用集合的主要好处之一。它把这个从 O(n^2) 变成 O(n)
          【解决方案7】:

          可以尝试数组(树)后缀算法,但是需要实现,看这个:

          Longest palindrome in a string using suffix tree

          【讨论】:

            【解决方案8】:

            您可以使用HashSet&lt;String&gt;ArrayList&lt;String&gt;,它们具有contains 方法。它将检查您的字符串是否已存储。
            HashSetArrayList 之间的区别在于 hashset 不允许重复值并且它不会保持顺序,而 arraylist 允许您重复并且它是有序集合。 但是 HashSet 比 arraylist 更有效地执行搜索操作。

            【讨论】:

            • 我不推荐arraylist,它必须检查所有项目,而HashSet必须检查具有相同hashCode()的那些.equals()...
            • 我不会调用 ArrayList 搜索对大型列表有效。
            • 我真的认为使用 Java 的内置数据类型进行此类搜索效率非常低。
            • @metsburg 所以你有更好的实现? ;-)
            • 感谢 cmets。是的,HashSet 比 ArrayList 更有效。我只是向他展示了 2 种方式及其区别
            猜你喜欢
            • 1970-01-01
            • 2015-03-03
            • 2020-09-18
            • 1970-01-01
            • 2017-02-28
            • 2011-08-13
            • 2012-09-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多