[英]More efficient alternative to these “for” loops?
我正在學習Java入門課程,而我的最新項目之一是確保數組不包含任何重復的元素(具有不同的元素)。 我使用了一個for循環和一個內部for循環,並且它起作用了,但是我聽說您應該避免在程序中使用許多迭代(並且我類中的其他方法也有很多迭代)。 有什么有效的替代方法嗎? 我當然不要求代碼,只是“概念”。 可能會有遞歸的方式做到這一點嗎? 謝謝!
數組大小通常<= 10。
/** Iterates through a String array ARRAY to see if each element in ARRAY is
* distinct. Returns false if ARRAY contains duplicates. */
boolean distinctElements(String[] array) { //Efficient?
for (int i = 0; i < array.length; i += 1) {
for (int j = i + 1; j < array.length; j += 1) {
if (array[i] == array[j]) {
return false;
}
}
} return true;
}
首先, array[i] == array[j]
測試引用是否相等。 這不是測試String
是否相等的方法。 我將每個元素添加到Set
。 如果沒有成功添加任何元素(因為它是重復元素),則Set.add(E)
返回false
。 就像是,
static boolean distinctElements(String[] array) {
Set<String> set = new HashSet<>();
for (String str : array) {
if (!set.add(str)) {
return false;
}
}
return true;
}
您可以在沒有短路的情況下渲染以上內容
static boolean distinctElements(String[] array) {
Set<String> set = new HashSet<>(Arrays.asList(array));
return set.size() == array.length;
}
“效率”幾乎總是一個權衡。 有時,有些算法會比其他算法好一些,但通常只有在某些情況下才更好。
例如,上面的代碼:時間復雜度為O(n^2)
。
一種改進可能是對字符串進行排序:然后,您可以通過比較元素是否等於其鄰居來比較字符串。 由於排序,這里的時間復雜度降低為O(n log n)
,它支配了元素的線性比較。
但是-如果您不想更改數組的元素-例如,您的代碼的其他部分依賴於它們的原始順序-現在,您還必須復制數組,然后對其進行排序,然后尋找重復項。 這不會增加總時間或存儲復雜性,但是會增加總時間和存儲 ,因為需要完成更多的工作並且需要更多的內存。
大數表示法只會使您無視乘法因素 ,從而束縛了時間。 也許您只能訪問一個非常慢的排序算法:實際上,事實證明,僅使用O(n^2)
循環會更快,因為那樣您就不必調用非常慢的排序了。
當您的輸入非常小時,可能會出現這種情況。 經常引用的算法是時間排序較差,但實際上在實踐中有用的算法是冒泡排序:在最壞的情況下,它是O(n^2)
,但是如果數組很小和/或接近排序,它就可以實際上可以非常快速地實現,並且非常容易實現-永遠不要忘記編寫和調試代碼的效率低下,以及當SO無法正常工作時不得不在SO上提問。
如果您知道元素已經排序,該怎么辦,因為您對它們的來源有所了解。 現在,您可以簡單地遍歷數組,比較鄰居,時間復雜度現在為O(n)
。 我不記得我在哪里讀的書,但是我曾經看到一篇博客文章說(我釋義):
一台給定的計算機永遠無法更快運行。 它只能做更少的工作。
如果您可以利用某些財產來減少工作量,那將提高效率。
因此,效率是一個主觀標准:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.