我已经阅读Eric Lippert 的博客有一段时间了(它非常好,你应该看看),在他的一篇文章的评论中,他提到他无意索引一系列数字,而只是枚举它们。
枚举和索引有什么区别,我到处搜索过?在我的搜索过程中,当迭代被带入方程式时,我变得更加困惑?有人可以解释这三个概念,甚至可以举个例子吗?在您将此标记为骗子之前,我已经看到了一些关于“迭代器与枚举器”的问题,但是我还没有看到一个正确的解释(因此是这个问题)。我感谢您的帮助。
我已经阅读Eric Lippert 的博客有一段时间了(它非常好,你应该看看),在他的一篇文章的评论中,他提到他无意索引一系列数字,而只是枚举它们。
枚举和索引有什么区别,我到处搜索过?在我的搜索过程中,当迭代被带入方程式时,我变得更加困惑?有人可以解释这三个概念,甚至可以举个例子吗?在您将此标记为骗子之前,我已经看到了一些关于“迭代器与枚举器”的问题,但是我还没有看到一个正确的解释(因此是这个问题)。我感谢您的帮助。
在对文章的评论中,Eric 回复了一个观察结果,即由于排列的大小呈指数增长,它将很快超过可以用 32 位表示的数字。Eric 的回答是他无意索引排列,他的意思是定义一个编号方案以获得排列的序列号。这就是为什么,他说,溢出 32 位不是他关心的问题之一:他的方法允许以某种顺序枚举或简单地“产生”所有排列,而不是提供一种根据某种编号方案获得排列的方法。N-th
将此与在不经过所有前述问题的情况下产生N-th
排列的问题中讨论的问题进行对比:在这里,作者想要对排列进行索引或赋予数字,因此整数的大小是他们关心的问题。
这是上面链接的问题中讨论的索引排列的示例:
1 ABC
2 ACB
3 BAC
4 BCA
5 CAB
6 CBA
此索引方案可让您回答两个问题:
BCA
?(是4个)X
,比如说,5?(是CAB
)这个问题可能比枚举所有排列更难,因为您需要生成一个编号方案。
从概念上讲,枚举器和迭代器都对序列知之甚少。他们通常可以:
修改集合时,它们的行为可能会有所不同。这些类型对于处理大量数据、流、LINQ 和延迟加载很有用,因为它们一次获取一个元素。要从序列中获取i元素,您必须遍历所有先前的元素,这是一个 O(N) 操作。您可以将它们视为一种linked list
数据结构。
索引器仅适用于固定长度的内存,即使底层存储可能会缩小和增长(就像在List<T>
类型中一样)。索引器知道什么是数据类型,它占用了多少存储空间,或者对对象的引用占用了多少存储空间。这允许索引器在 O(1) 中从序列中获取任何项目,缺点是您必须将所有数据存储在内存中。它只是将索引乘以元素的大小并将结果添加到起始地址 - 因此它获得了所需对象的值或引用。您可以将索引器视为一种array
数据结构。
你只能做真实的index
事情。你可以索引一个using或者你可以索引一个(至少在 C# 中,更正式的计算机科学的人会畏缩)。array
operator []
list
您不能索引 an,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];
这不是真的,里面没有数据number
,只是承诺提供枚举数据。您需要将其具体化以获得真实数据:
var number = GetNumbers();
这将产生无数个。它不是真实数据,它是一种在枚举后如何生成真实数据的秘诀:
public IEnumerable<int> GetNumbers()
{
while(true) yield return 1;
}