我试图实现在问题中找到的解决方案之一C# Permutation of an array of arraylists? 它应该执行笛卡尔积,但是它会返回正确数量的列表,但每个列表总是只是每个阵列的第一个。代码和结果如下。使用枚举的C#中的笛卡尔积
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace TestCartProd
{
class MainClass
{
public static void Main (string[] args)
{
string[][] myList = new string[3][];
myList[0] = new string[] { "1", "5", "3", "9" };
myList[1] = new string[] { "2", "3" };
myList[2] = new string[] { "a", "93" };
List<IEnumerable<string>> v = GetPermutations (myList).ToList();
foreach (IEnumerable t in v) {
foreach (string u in t) {
Console.Write (u);
}
Console.WriteLine();
}
}
public static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<IEnumerable<T>> lists)
{
// Check against an empty list.
if (!lists.Any())
{
yield break;
}
// Create a list of iterators into each of the sub-lists.
List<IEnumerator<T>> iterators = new List<IEnumerator<T>>();
foreach (var list in lists)
{
var it = list.GetEnumerator();
// Ensure empty sub-lists are excluded.
if (!it.MoveNext())
{
continue;
}
iterators.Add(it);
}
bool done = false;
while (!done)
{
// Return the current state of all the iterator, this permutation.
yield return from it in iterators select it.Current;
// Move to the next permutation.
bool recurse = false;
var mainIt = iterators.GetEnumerator();
mainIt.MoveNext(); // Move to the first, succeeds; the main list is not empty.
do
{
recurse = false;
var subIt = mainIt.Current;
if (!subIt.MoveNext())
{
subIt.Reset(); // Note the sub-list must be a reset-able IEnumerable!
subIt.MoveNext(); // Move to the first, succeeds; each sub-list is not empty.
if (!mainIt.MoveNext())
{
done = true;
}
else
{
recurse = true;
}
}
}
while (recurse);
}
}
}
}
结果: 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A 12A
的'it'在'它。当前''将永远是新创建的(通过LINQ语句:'从它迭代器中'),所以当然会始终返回第一个元素 - btw:你可以用LINQ和递归完成所有这些工作 - 可能不是* performant *但它会让你轻松实现第一步 – Carsten
谢谢!这很好用 –