![](/img/trans.png)
[英]Most efficient way to find unique intersections from two different ArrayLists?
[英]Most efficient way to find unique entries in a large data set
在開始之前,我要明確指出這是一項作業,並且我不希望得到完整的編碼答案。 我所尋求的只是建議,或者是有助於我的代碼片段。
因此,我正在讀取大約900,000個單詞,這些單詞全部存儲在arrayList中。 我需要使用Java中的排序數組(或arraylist)來計算唯一單詞。
到目前為止,我只是循環遍歷給定的arrayList並使用
Collections.sort(words);
和Collections.binarySearch(words, wordToLook);
實現它,如下所示:
OrderedSet set = new OrderedSet();
for(String a : words){
if(!set.contains(a)){
set.add(a);
}
}
和
public boolean contains(String word) {
Collections.sort(uniqueWords);
int result = Collections.binarySearch(uniqueWords, word);
if(result<0){
return false;
}else{
return true;
}
}
這段代碼的運行時間大約為60秒,但是我想知道是否還有更好的方法,因為每次添加元素時運行排序效率都非常低(但是如果我要使用二進制搜索的話,這很必要)。
任何形式的反饋將不勝感激。 謝謝。
我不會使用排序數組。 我將創建一個Map<String, Integer>
,其中鍵是您的單詞,值是單詞出現次數的計數。 當您閱讀每個單詞時,請執行以下操作:
Integer count = map.get(word);
if (count == null) {
count = 0;
}
map.put(word, count + 1);
然后,只需遍歷地圖的條目集,然后對計數進行任何處理即可。
如果您知道或可以估計唯一單詞的數量,則應在HashMap構造函數中使用此數字(這樣就不必多次擴展地圖)。
如果使用排序數組,則運行時間不能與NlogN成正比(其中N是列表中的單詞數)。 如果使用HashMap,則可以實現隨N線性增長的運行時(您節省了logN的因數)。
使用Map的另一個優勢是,所使用的內存與唯一單詞的數量成正比,而不是與單詞的總數成比例(假設您在讀取單詞時構建了Map,而不是將所有單詞都讀入一個集合然后添加它們到地圖)。
因此,您需要使用排序數組。 可以,因為您(尚未)在現實世界中編程。
我將建議兩種選擇:
第一種使用二進制搜索(您在當前代碼中使用的二進制搜索)。
我將創建一個包含兩個字段的類:單詞(字符串)和該單詞的計數(整數)。 您將構建這些類的排序數組。
從一個空數組開始,然后在閱讀每個單詞時將其添加到其中。 對於每個單詞,在要構建的數組中進行二進制搜索。 搜索將找到包含單詞的條目(您將增加計數),或者確定單詞尚未出現在數組中。
當二分查找結束而沒有找到單詞時,您將創建一個新對象來容納單詞+計數,並將其添加到搜索結束位置的數組中(請注意確保邏輯確實將其正確放置以使您的列表保持排序)。 當然,您將新單詞的計數設置為1。
另一種選擇:
將所有單詞讀入列表並進行排序。 排序后,所有重復項將在列表中彼此相鄰。
您將在此排序后的列表中查找一次,並隨即創建一個單詞+計數的列表。 如果您看到的下一個單詞與最后一個單詞+計數相同,則增加計數。 如果是新單詞,則將新單詞+計數添加到結果列表中,計數為= 1。
public static int countUnique(array) {
if(array.length == 0) return 0;
int count = 1;
for i from 1 to array.length - 1 {
if(!array[i].equals(array[i - 1])) count++;
}
return count;
}
這是偽代碼中的O(N)
算法,用於計算已排序數組中唯一條目的數量。 其背后的想法是,我們計算相等元素組之間的過渡次數。 然后,唯一條目的數量是轉換數量加一個(對於第一個條目)。
希望您能看到對元素進行排序后如何將此算法應用於數組。
您總是可以使用比較器來獲取唯一值。
List newList = new ArrayList(new Comparator() {
@Override
public int compare(words o1, words o2) {
if(o1.equalsIgnoreCase(o2)){
return 0;
}
return 1;
}
});
現在計數:
單詞-newList =否。 重復值。
希望這可以幫助!!!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.