Java:如何在数组中搜索字符串的一部分

时间:2011-10-06 10:15:35

标签: java search sorting

我有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;

    }

提前致谢。

6 个答案:

答案 0 :(得分:2)

最基本的方法是

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

您可以改进此版本,如果您只关注startWith而不是contains,那么您可以在HashMap中分发字词,并且您将缩小搜索范围

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

使用排序

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

使用预先排序的结构

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

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

如果您阅读的内容多于写作,则此功能特别有用。也许订购字符串有点贵,但一旦订购,您可以非常快地找到它们(O(log n))。

不区分大小写的比较

您可以为树集提供Comparator<String>,以指示它必须如何排序字符串。你可以实现它,或者在那里有一个预建的不区分大小写的比较器。

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

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

答案 3 :(得分:1)

另请参阅trie数据结构。 This问题有用。我认为它getPrefixedBy()会比你能用手快速滚动的任何东西更有效率。

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

答案 4 :(得分:0)

以下是一个类似的例子:

- &GT; http://samuelsjoberg.com/archive/2009/10/autocompletion-in-swing

答案 5 :(得分:0)

如果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;