2013-05-11 90 views
5

我一直在閱讀Eric Lippert's blog一段時間(這很好,你應該檢查出它)和在他的一個posts的評論中,他提到他沒有意圖索引一系列數字而只是列舉它們。枚舉與索引與迭​​代

枚舉和索引有什麼區別,我到處搜索過?在我的搜索過程中,當迭代進入等式時,我變得更加困惑了?有人可以解釋這3個概念,甚至可以舉個例子嗎?在你將這個標記爲一個複製之前,我已經看到了一些關於「Iterator vs Enumerator」的問題,但是我仍然看到了一個正確的解釋(因此,這個問題)。我感謝您的幫助。

回答

4

在Eric對文章的評論中回答說,由於置換的規模呈指數級增長,所以它會很快超過可用32位表示的數字。埃裏克的回答是,他不打算索引排列,這意味着定義一個編號方案,以獲得排列的連續編號。這就是爲什麼他說,溢出32位並不是他的擔心之一:他的方法允許列舉,或者簡單地「產生」,所有排列在的一些順序,而不是提供一種方法來獲得N-th排列到一些編號方案。

將此問題與question about producing N-th permutation without going through all the preceding ones中討論的問題進行對比:在此,作者希望索引或給出數字排列,因此整數的大小是他們關心的問題。

下面是上面鏈接中的問題討論索引排列的例子:

1 ABC 
2 ACB 
3 BAC 
4 BCA 
5 CAB 
6 CBA 

此索引模式可以讓您回答兩個問題:

  • 什麼是特殊排列的號碼,說,BCA?(它是4)
  • 什麼是置換數X,比如5? (它的CAB

這個問題可能比枚舉所有排列難一些,因爲你需要產生一個編號方案。

+0

偉大的東西,我很欣賞你的幫助。現在我看到它很明顯......但迭代呢,它與枚舉有什麼不同呢? – 2013-05-11 10:46:56

+1

@DimitarDimitrov在這種情況下枚舉和迭代是非常密切相關的:枚舉意味着產生所有的排列,而迭代意味着在循環中經歷它們。要列舉一個序列,你需要知道如何去做;迭代它,你需要真正做到這一點。在C#的上下文中,可以通過提供帶有延遲執行的IEnumerabl 來枚舉序列。然後他可以選擇迭代這個序列,比如用foreach循環,或者做其他的事情 - 比如說,先抽取幾個元素,然後扔掉枚舉的其餘部分。 – dasblinkenlight 2013-05-11 10:59:28

+0

因此,僅僅總結一下,枚舉是「產生」一系列排列的行爲,迭代是「貫穿序列」的行爲?此外,不同的執行基本上是「不知道如何按要求列舉和執行」,而不是事先做好必要的準備? – 2013-05-11 11:45:46

1

從概念上講,枚舉器和迭代器對序列知之甚少。他們通常可以:

  • 獲取下一個項目
  • 檢查當前元素是最後一個

他們可能會表現不同,當集合被修改。這些類型可用於處理大量數據,流,LINQ和延遲加載,因爲它們一次獲取一個元素。要從一個序列中獲取元素,您必須遍歷所有先前的元素,這是一個O(N)操作。你可以把它們想象成一個linked list數據結構。

索引器只能用於固定長度的內存,即使底層存儲可能會縮小和增長(如類似於List<T>類型)。索引器知道什麼是數據類型,需要多少存儲空間,或者對象的引用需要多少存儲空間。這允許索引器從O(1)中的序列中獲取任何項目,但不利的一面是您必須將所有數據存儲在內存中。它只是將索引乘以元素的大小,並將結果添加到起始地址 - 因此它會獲取所需對象的值或引用。您可以將索引器視爲array數據結構。

1

你只能index東西,那就是。您可以使用operator []array編制索引,或者您可以索引list(至少在C#中,進入更正式計算機科學的人將會畏縮)。

您不能索引IEnumerable<T>,因爲要枚舉簡單的方法表示您可以按順序遍歷所有項目。但是你不能跳轉到特定的項目。

string text = "hello"; 

這是枚舉:

foreach(var c in text) Console.WriteLine(c); 

此使用索引:

for(int i = 0 ; i < text.Length ; i++) Console.WriteLine(text[i]); 

真正數據:

var arr = new int[15]; 

這不是realnumber, 中沒有數據只是傳遞枚舉數據的承諾。 您需要兌現它有真正數據:

var number = GetNumbers(); 

這將產生那些無盡的數量。這不是真實的數據, 這是種配方的如何產生真實的數據,一旦你枚舉它:

public IEnumerable<int> GetNumbers() 
{ 
    while(true) yield return 1; 
} 
+0

這幫了很多!我希望我能接受2個答案......或者至少多投一票! – 2013-05-11 11:47:30