【问题标题】:How to search an array for a part of string?如何在数组中搜索字符串的一部分?
【发布时间】:2011-12-02 03:25:10
【问题描述】:

我有一个arraylist<string> 的单词。我使用Collections.sort(wordsList);对其进行排序

我将这个数组用于一个自动建议下拉框,这样当用户输入一个字母时,他们会得到一个与他们输入的内容相似的建议列表。

我如何在这个数组中搜索字符串前缀,假设用户输入“mount”并且数组包含单词“mountain”,我如何搜索这个数组并返回相似的值。

到目前为止,这是我的代码:

public List<Interface> returnSuggestedList(String prefix) {
    String tempPrefix = prefix;
    suggestedPhrases.clear();
    //suggestedPhrases = new ArrayList<Interface>();
    //Vector<String> list = new Vector<String>();
    //List<Interface> interfaceList = new ArrayList<Interface>();
    Collections.sort(wordsList);
    System.out.println("Sorted Vector contains : " + wordsList);
    int i = 0;
    while (i != wordsList.size()) {
        int index = Collections.binarySearch(wordsList, prefix);
        String tempArrayString = wordsList.get(index).toString();
        if (tempArrayString.toLowerCase().startsWith(prefix.toLowerCase())) {
            ItemInterface itemInt = new Item(tempArrayString);
            suggestedPhrases.add(itemInt);
            System.out.println(suggestedPhrases.get(i).toString());
            System.out.println("Element found at : " + index);
        }
        i++;
    }
    return suggestedPhrases;
}

【问题讨论】:

    标签: java string sorting search string-comparison


    【解决方案1】:

    最基本的方法是

    List<String> result = new ArrayList<String>();
    for(String str: words){
      if(str.contains(keyword){
        result.add(str);
      }
    }
    

    你可以改进这个版本,如果你只关心startWith而不是contains,那么你可以在HashMap中分配单词,你会缩小搜索范围

    【讨论】:

    • 我认为 startsWith 与 OP 的要求最相关。
    【解决方案2】:

    对于这个任务,有比排序的字符串数组更好的数据结构。你可能看起来例如在DAWG (Directed acyclic word graph)

    【讨论】:

      【解决方案3】:

      如果wordList 是固定的(不会从一种方法调用更改为另一种方法调用),则应将其排序到其他位置,因为排序成本很高,并将其存储为小写。

      在该方法的其余部分中,您将执行以下操作:

      List<String> selected = new ArrayList<String>();
      
      for(String w:wordList){
          if(w.startsWith(prefix.toLower())) // or .contains(), depending on 
              selected.add(w);     // what you want exactly 
      }
      
      return selected;
      

      【讨论】:

        【解决方案4】:

        另见trie 数据结构。 This question 有有用的信息。我应该认为它的getPrefixedBy() 会比你可以快速手动滚动的任何东西更有效。

        当然,这仅适用于前缀搜索。包含搜索是完全不同的野兽。

        【讨论】:

          【解决方案5】:

          正如@Jiri 所说,您可以使用 DAWG,但如果您不想走那么远,您可以做一些简单而有用的事情。

          利用排序

          • 如果要对单词数组进行排序,请先执行此操作。不要每次都排序
          • 排序后,您可以在列表中找到匹配的第一个和最后一个单词。使用 list.subList(from, to) 返回子列表。添加一个会更优化一点。

          使用预先排序的结构

          • 使用TreeSet&lt;String&gt; 存储字符串(将在内部排序)。
          • 然后使用treeSet.subSet(from, true, to, false);

          其中from 是前缀,to 是“前缀加一个字符”。例如,如果您要查找abc,则to 必须是abd。如果您不想进行该字符转换,您可以请求treeSet.headSet(from) 并对其进行迭代,直到没有更多前缀为止。

          如果你读的比写的多,这特别有用。也许订购字符串有点贵,但订购后您可以很快找到它们 (O(log n))。

          不区分大小写的比较

          您可以为树集提供Comparator&lt;String&gt;,以指示它必须如何对字符串进行排序。你可以实现它,或者那里可能有一个预构建的不区分大小写的比较器。

          无论如何它的代码应该是:

          int compare(String a, String b) {
             return a.toLowerCase().compareTo(b.toLowerCase());
          }
          

          【讨论】:

            【解决方案6】:

            【讨论】:

              猜你喜欢
              • 2012-03-03
              • 1970-01-01
              • 2012-03-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-10
              • 1970-01-01
              相关资源
              最近更新 更多