2013-05-11 95 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