2011-10-06 56 views
3

我有一個arraylist<string>的話。我使用Collections.sort(wordsList);Java:如何搜索字符串的一部分數組

我正在使用這個數組作爲自動建議下拉框,以便當用戶輸入一個字母時,他們會得到一個類似於他們輸入內容的建議列表。

我該如何去搜索這個數組中的字符串前綴,比如說用戶鍵入「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; 

    } 

在此先感謝。

回答

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; 
2

最基本的方法是

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

您可以改善這個版本,如果你只用startWith,而不是contains關注,那麼你可以在一個HashMap分配的話,你將不得不縮小搜索

1

由於@Jiri說,你可以使用一個耶,但如果你不想去那麼遠,你可以做一些簡單的和有用的東西。

利用分揀

  • 如果你想的話的陣列做以前那種。不要每次都排序
  • 由於它已排序,所以您可以在列表中找到匹配的第一個和最後一個單詞。使用list.subList(from,to)返回子列表。添加每一個都會更好一點。

使用預先排序結構

  • 使用TreeSet<String>用於存儲字符串(在將在內部排序)。
  • 然後使用treeSet.subSet(from, true, to, false);

其中from是前綴,to是「前綴加一個字符」。例如,如果您正在尋找abcto必須是abd。如果你不想進行char轉換,你可以詢問treeSet.headSet(from)並迭代它直到沒有更多的前綴。

如果您閱讀的內容比您撰寫的內容多,這將特別有用。也許訂購字符串有點貴,但一旦訂購,您可以非常快地找到它們(O(log n))。

不區分大小寫比較

您可以提供Comparator<String>樹,以表明它必須如何訂購字符串設定。你可以實現它,或者在那裏有一個預先建立的不區分大小寫的比較器。

反正它的代碼應該是:

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

另見trie數據結構。 This問題有用的信息。我認爲它的getPrefixedBy()比任何你可以快速手卷的東西都更有效率。

當然,這隻適用於前綴搜索。包含搜索是一個完全不同的野獸。

+0

+1 Trie是一個偉大的自動建議數據結構 – Qwerky