IEnumerable
通过使用和的通用版本来减少您的困惑(?)IEnumerator
。
可枚举的排列是IEnumerable<IEnumerable<T>>
。所以你可能有类似的东西
IEnumerable<IEnumerable<T>> GetPermutations(IEnumerable<T> sequence)
{
return new Permuter<T>(sequence);
}
和
public class Permuter<T> : IEnumerable<IEnumerable<T>> { ... }
此外,我见过不止一种情况,其中一种类型同时实现了IEnumerable<T>
and IEnumerator<T>
; 它的 GetEnumerator 方法很简单return this;
。
不过,我认为这样的类型需要是一个结构,因为如果它是一个类,如果在第一次枚举完成之前第二次调用 GetEnumerator(),就会遇到各种问题。
编辑:消费置换器
var permuter = GetPermutations(sequence);
foreach (var permutation in permuter)
{
foreach (var item in permutation)
Console.Write(item + "; ");
Console.WriteLine();
}
假设输入序列为 { 1, 2, 3 },则输出为
1; 2; 3;
1; 3; 2;
2; 1; 3;
2; 3; 1;
3; 1; 2;
3; 2; 1;
编辑:
这是一个超级低效的实现来说明这个建议:
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();
}
}