簡體   English   中英

這些“ for”循環的更有效替代方案?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM