On dirait que vous voulez que cette fonction de Eric Lippert's blog post écrite en réponse à Generating all Possible Combinations:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item}));
}
qui vous permettent d'écrire du code comme ceci:
int[][] items = {
new[] { 11001, 54010, 60621 },
new[] { 11001, 60621 },
new[] { 60621 }
};
var routes = CartesianProduct(items);
foreach (var route in routes)
Console.WriteLine(string.Join(", ", route));
Et obtenir une sortie comme ceci:
11001, 11001, 60621
11001, 60621, 60621
54010, 11001, 60621
54010, 60621, 60621
60621, 11001, 60621
60621, 60621, 60621
EDIT: Voici la version VB.NET (en VS2010)
Imports System.Runtime.CompilerServices
Module Module1
<Extension()>
Private Function CartesianProduct(Of T)(
ByVal sequences As IEnumerable(Of IEnumerable(Of T))) _
As IEnumerable(Of IEnumerable(Of T))
Dim emptyProduct As IEnumerable(Of IEnumerable(Of T)) =
New IEnumerable(Of T)() {Enumerable.Empty(Of T)()}
Return sequences.Aggregate(
emptyProduct,
Function(accumulator, sequence)
Return (From accseq In accumulator
From item In sequence
Select accseq.Concat(New T() {item}))
End Function)
End Function
Sub Main(ByVal args As String())
Dim items = New Integer()() {New Integer() {11001, 54010, 60621},
New Integer() {11001, 60621},
New Integer() {60621}}
Dim routes = items.CartesianProduct()
Dim route As IEnumerable(Of Integer)
For Each route In routes
Console.WriteLine(String.Join(", ", route))
Next
End Sub
End Module
Bien sûr, si vous ne voulez pas que ce soit LINQ, voici une implémentation récursive complètement LINQ sans:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
var accum = new List<T[]>();
var list = sequences.ToList();
if (list.Count > 0)
CartesianRecurse(accum, new Stack<T>(), list, list.Count - 1);
return accum;
}
static void CartesianRecurse<T>(List<T[]> accum, Stack<T> stack,
List<IEnumerable<T>> list, int index)
{
foreach (T item in list[index])
{
stack.Push(item);
if (index == 0)
accum.Add(stack.ToArray());
else
CartesianRecurse(accum, stack, list, index - 1);
stack.Pop();
}
}
Il ne retourne pas les éléments dans le même ordre que la première fonction, mais est autrement identique sur le plan fonctionnel. Si vous ne l'aimez pas LINQ ou récursion, voici une méthode unique LINQ moins qui fait la même chose que la version récursive:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
var accum = new List<T[]>();
var list = sequences.ToList();
if (list.Count > 0)
{
var enumStack = new Stack<IEnumerator<T>>();
var itemStack = new Stack<T>();
int index = list.Count - 1;
var enumerator = list[index].GetEnumerator();
while (true)
if (enumerator.MoveNext())
{
itemStack.Push(enumerator.Current);
if (index == 0)
{
accum.Add(itemStack.ToArray());
itemStack.Pop();
}
else
{
enumStack.Push(enumerator);
enumerator = list[--index].GetEnumerator();
}
}
else
{
if (++index == list.Count)
break;
itemStack.Pop();
enumerator = enumStack.Pop();
}
}
return accum;
}
Je ne comprends pas votre logique pour générer des itinéraires ... Qu'est-ce que les "items" représentent quand même? S'il vous plaît donner plus de détails sur ce que vous essayez de faire! –
duplication possible de [Génération de toutes les combinaisons possibles] (http: // stackoverflow.com/questions/3093622/generation-all-possible-combinations) – Gabe
Vous avez ce C# étiqueté. Voulez-vous une solution VB? – Gabe