jtf*_*ank 7 c# ienumerable ienumerator enumeration
我有一个名为GenericPermutations的类,它既是可枚举的又是枚举器.它的工作是获取一个有序的对象列表,并按顺序迭代它们的每个排列.
例如,此类的整数实现可以迭代以下内容:
GenericPermutations<int> p = new GenericPermutations<int>({ 1, 2, 3 });
p.nextPermutation(); // 123
p.nextPermutation(); // 132
p.nextPermutation(); // 213
// etc.
Run Code Online (Sandbox Code Playgroud)
所以它的可枚举性就是它包含了你可以枚举的事物的"列表".它也是一个普查员,因为它的工作涉及寻找下一个排列.
问题:我目前正在尝试将IEnumerator和IEnumerable与这个类集成,在我看来它应该是两者(而不是使用子类作为IEnumerable).到目前为止,我已经避免了通过在GetEnumerator方法中传递新的GenericPermutation对象来尝试从中获取两个枚举器的问题.
这是一个坏主意吗?还有什么我应该考虑的吗?
通过使用仿制药,减少你的困惑(?)IEnumerable和IEnumerator.
可枚举的排列是IEnumerable<IEnumerable<T>>.所以你可能有类似的东西
IEnumerable<IEnumerable<T>> GetPermutations(IEnumerable<T> sequence)
{
return new Permuter<T>(sequence);
}
Run Code Online (Sandbox Code Playgroud)
和
public class Permuter<T> : IEnumerable<IEnumerable<T>> { ... }
Run Code Online (Sandbox Code Playgroud)
此外,我已经看到多于一个的情况下的单个类型实现两个IEnumerable<T>和IEnumerator<T>; 它的GetEnumerator方法很简单return this;.
我认为这样的类型需要是一个结构,因为如果它是一个类,如果你在第一个枚举完成之前第二次调用GetEnumerator(),你就会遇到各种各样的问题.
编辑:消费permuter
var permuter = GetPermutations(sequence);
foreach (var permutation in permuter)
{
foreach (var item in permutation)
Console.Write(item + "; ");
Console.WriteLine();
}
Run Code Online (Sandbox Code Playgroud)
假设输入序列是{1,2,3},则输出为
1; 2; 3;
1; 3; 2;
2; 1; 3;
2; 3; 1;
3; 1; 2;
3; 2; 1;
Run Code Online (Sandbox Code Playgroud)
编辑:
这是一个超低效的实现来说明这个建议:
public class Permuter<T> : IEnumerable<IEnumerable<T>>
{
private readonly IEnumerable<T> _sequence;
public Permuter(IEnumerable<T> sequence)
{
_sequence = sequence;
}
public IEnumerator<IEnumerable<T>> GetEnumerator()
{
foreach(var item in _sequence)
{
var remaining = _sequence.Except(Enumerable.Repeat(item, 1));
foreach (var permutation in new Permuter<T>(remaining))
yield return Enumerable.Repeat(item, 1).Concat(permutation);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1092 次 |
| 最近记录: |