2014-03-06 66 views
0

我試圖根據文本文件搜索常用英語單詞數組,以查看其中是否包含特定單詞。由於這個數組有大於700,000個單詞,並且如果在數組中有多達1000個單詞需要被檢查多次,我認爲根據長度將單詞分成單獨的數組或列表會更有效率。有沒有簡單的方法來做到這一點,而不使用開關或大量的if語句?像這樣:基於Java中的單詞長度將常見英語單詞陣列拆分爲單獨的列表/數組

for(int i = 0; i < commonWordArray.length; i++) { 
    if(commonWordArray[i].length == 2) { 
     twoLetterList.add(commonWordArray[i]); 
    else if(commonWordArray[i].length == 3) { 
     threeLetterList.add(commonWordArray[i]); 
    else if(commonWordArray[i].length == 4) { 
     fourLetterList.add(commonWordArray[i]); 
    } 
    ...etc 
} 

然後做同樣的事情檢查句話的時候:

for(int i = 0; i < checkWords.length; i++) { 
    if(checkWords[i].length == 2) { 
     if(twoLetterList.contains(checkWords[i])) { 
     ...etc 
} 
+1

作爲存儲大陣在內存中可能是一個殺手,constatn對文件的訪問可能會降低你wodn,爲什麼你不想來存儲你的話在數據庫(即H2),只是運行簡單的查詢? – user902383

+0

Java是否支持散列或關聯數組?如果是這樣,爲什麼不創建一個關鍵詞的散列,使查找變得容易。或者,你是否允許特定詞的子串? – sln

+0

@ user902383我確實認爲這是一種更好的方法,但是這對我的研究論文中的一個簡單的密碼分析工具來說非常重要,在這裏可以將常用單詞文件作爲參數進行傳遞 –

回答

1

步驟1

創建字桶。

ArrayList<ArrayList<String>> buckets = new ArrayList<>(); 
for(int i = 0; i < maxWordLength; i++) { 
    buckets.add(new ArrayList<String>()); 
} 

步驟2

單詞添加到您的水桶。

buckets.get(word.length()).add(word); 

這種方法的缺點是您的一些桶可能未被使用。這不是一個問題,如果你只是過濾共同英文單詞,因爲它們不超過30個字符的長度。創建10-15個額外的列表對於計算機來說是一個微不足道的開銷。最大的不常見但非技術性詞彙是183個字符。技術詞彙超過180,000個字符,這一點顯然不切合實際。

這種方法的好處是,ArrayList.get()ArrayList.add()在恆定(O(1))的時間都運行。

1

使用List<Set<String>> sets。也就是說,給定String word,首先找到適當的集合(Set<String> set = sets.get(word.length)) - 根據需要創建集合,如果需要則擴展列表。然後做一個set.add(word)。完成!

編輯/提示:一個(好的)程序員應該是懶惰的 - 如果你需要做/寫同樣的東西兩次,你在做東西錯誤。

0

假設你已經有了內存(你目前的方法依賴於此),爲什麼不只是一個Set<String>?更簡單,更快。

0

如果您想使用多個字符串進行搜索,您可能需要嘗試類似Aho Corasick算法。

或者,您可能想要解決問題,並檢查700k數組中的字符串是否在1k數組中。對此,你不會有內存問題(imho),你可以用一個簡單的字典(平衡樹)來做到這一點。所以你有700k log2(1000)。

0

使用Trie,這是一種內存高效的存儲機制,擅長存儲單詞並檢查它們是否存在。

自己實現一個是一個有趣的練習,或看看現有的實現。