Ich kann nicht sagen, ob die folgende ist der einfachste Weg, aber es ist IMO die effizienteste Art und Weise. Es ist im Grunde eine verallgemeinerte Version der meine Antwort auf die Looking at each combination in jagged array:
public static class Algorithms
{
public static IEnumerable<T[]> GenerateCombinations<T>(this IReadOnlyList<IReadOnlyList<T>> input)
{
var result = new T[input.Count];
var indices = new int[input.Count];
for (int pos = 0, index = 0; ;)
{
for (; pos < result.Length; pos++, index = 0)
{
indices[pos] = index;
result[pos] = input[pos][index];
}
yield return result;
do
{
if (pos == 0) yield break;
index = indices[--pos] + 1;
}
while (index >= input[pos].Count);
}
}
}
Sie können die Erklärung in der verknüpften Antwort sehen (kurz es verschachtelte Schleifen Emulation). Auch da er aus Performancegründen den internen Puffer ohne Klonen erzeugt, müssen Sie ihn klonen, wenn Sie das Ergebnis für die spätere Verarbeitung speichern wollen.
Verwendungsbeispiel:
var list1 = new List<int> { 1 };
var list2 = new List<int> { 1, 2 };
var lists = new[] { list1, list2 };
// Non caching usage
foreach (var combination in lists.GenerateCombinations())
{
// do something with the combination
}
// Caching usage
var combinations = lists.GenerateCombinations().Select(c => c.ToList()).ToList();
UPDATE: Die GenerateCombinations
ist ein Standard-C# iterator Verfahren und die Implementierung emuliert grundsätzlich N
verschachtelten Schleifen (wobei N
ist die input.Count
) wie folgt aus (in Pseudocode):
for (int i 0 = 0; i < Eingabe [0] .Zahl; i ++)
for (int i 1 = 0; i < Eingang [1] .Count; i ++)
for (int i 2 = 0; i < Eingang [2] .Count; i ++)
...
for (int i N-1 = 0; i N-1 < Eingang [N-1 ].Anzahl; i N-1 ++)
Ausbeute {input [0] [i 0], input [1] [i ], input [2] [i 2], ..., Eingang [N-1] [i N-1]}
oder es anders zeigt:
for (indices[0] = 0; indices[0] < input[0].Count; indices[0]++)
{
result[0] = input[0][indices[0]];
for (indices[1] = 0; indices[1] < input[1].Count; indices[1]++)
{
result[1] = input[1][indices[1]];
// ...
for (indices[N-1] = 0; indices[N-1] < input[N-1].Count; indices[N-1]++)
{
result[N-1] = input[N-1][indices[N-1]];
yield return result;
}
}
}
Mögliches Duplikat von [Alle Permutationen einer Zeichenkette/inte auflisten ger] (http://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer) –
Was meinst du mit einer Reihe von Listen? Ihr Beispiel zeigt nur zwei. Hast du nur zwei oder hast du mehr? Sind Sie nach dem kartesischen Produkt aller Listen? – Enigmativity
Meinst du Permutationen? Oder meinst du wirklich Kombinationen (auch kartesisches Produkt)? Kombinationen von zwei Listen ABC und 12 wäre A1, B1, C1, A2, B2, C2 –