笛卡尔积+ N x M动态arrays

我已经看了几个小时的解决方案,没有任何成功。 希望有人可以帮助我。

我有M个原始邮政编码的N项动态数组。

例如:

项目1:11001,54010,60621项目2:11001,60621项目3:60621

我想创建一个如下所示的新数组:

路线1:11001,11001,60621路线2:11001,60621,60621路线3:54010,11001,60621

等 – 直到6号公路。

建议?

———————-有没有办法在不使用Linq的情况下实现这一目标? VB.net和Linq不一起:)

听起来你想要这个函数来自Eric Lippert的博客文章 ,以回应Generate all Possible Combinations :

public static IEnumerable> CartesianProduct( this IEnumerable> sequences) { IEnumerable> emptyProduct = new[] { Enumerable.Empty() }; return sequences.Aggregate( emptyProduct, (accumulator, sequence) => from accseq in accumulator from item in sequence select accseq.Concat(new[] {item})); } 

那会让你写这样的代码:

 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)); 

得到这样的输出:

 11001,11001,60621
 11001,60621,60621
 54010,111001,60621
 54010,60621,60621
 60621,111001,60621
 60621,60621,60621

编辑:这是VB.NET版本(在VS2010中)

 Imports System.Runtime.CompilerServices Module Module1  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 

当然,如果你不想要任何LINQ,这里是一个完全无LINQ的递归实现:

 public static IEnumerable> CartesianProduct( this IEnumerable> sequences) { var accum = new List(); var list = sequences.ToList(); if (list.Count > 0) CartesianRecurse(accum, new Stack(), list, list.Count - 1); return accum; } static void CartesianRecurse(List accum, Stack stack, List> 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(); } } 

它不会以与第一个函数相同的顺序返回项目,但在function上相同。 如果你不喜欢LINQ 递归,这里是一个单一的LINQ-less方法,与递归版本做同样的事情:

 public static IEnumerable> CartesianProduct( this IEnumerable> sequences) { var accum = new List(); var list = sequences.ToList(); if (list.Count > 0) { var enumStack = new Stack>(); var itemStack = new Stack(); 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; } 

您可以使用linq:

 var item1 = new[] { 11001, 54010, 60621 }; var item2 = new[] { 11001, 60621 }; var item3 = new [] { 60621 }; IEnumerable cartesian = from i1 in item1 from i2 in item2 from i3 in item3 select new[] { i1, i2, i3 }; 

您要做的是生成数组中每个项目的组合。

这是N == 3的硬编码示例:

  var array1 = new[] { 1101, 5410, 60621 }; var array2 = new[] { 1101, 60621 }; var array3 = new[] { 60621 }; foreach (var a in array1) { foreach (var b in array2) { foreach (var c in array3) { Console.WriteLine("{0},{1},{2}", a, b, c); } } } 

看看你是否可以适应N个案例。