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

Posted

技术标签:

【中文标题】如何在数组中搜索字符串的一部分?【英文标题】: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;

【问题讨论】:

【参考方案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】:

这是一个类似的例子:

->http://samuelsjoberg.com/archive/2009/10/autocompletion-in-swing

【讨论】:

以上是关于如何在数组中搜索字符串的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

如何在数组jQuery中查找字符串的一部分

在 php 数组中搜索部分字符串匹配 [重复]

Java - 在字符串数组中搜索字符串[重复]

在PHP中搜索字符串或字符串的一部分

如何在 Perl 数组中搜索匹配的字符串?

如果我有多个数组并且我想在所有数组中搜索,如何在 java 中搜索字符串?