如何在数组中搜索字符串的一部分?
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<String>
存储字符串(将在内部排序)。
然后使用treeSet.subSet(from, true, to, false)
;
其中from
是前缀,to
是“前缀加一个字符”。例如,如果您要查找abc
,则to
必须是abd
。如果您不想进行该字符转换,您可以请求treeSet.headSet(from)
并对其进行迭代,直到没有更多前缀为止。
如果你读的比写的多,这特别有用。也许订购字符串有点贵,但订购后您可以很快找到它们 (O(log n)
)。
不区分大小写的比较
您可以为树集提供Comparator<String>
,以指示它必须如何对字符串进行排序。你可以实现它,或者那里可能有一个预构建的不区分大小写的比较器。
无论如何它的代码应该是:
int compare(String a, String b)
return a.toLowerCase().compareTo(b.toLowerCase());
【讨论】:
【参考方案6】:这是一个类似的例子:
->http://samuelsjoberg.com/archive/2009/10/autocompletion-in-swing
【讨论】:
以上是关于如何在数组中搜索字符串的一部分?的主要内容,如果未能解决你的问题,请参考以下文章