我已经看了几个小时没有成功的解决方案。希望有人可以帮助我。
我在M原始邮政编码上有N个动态数组。
例如:
项目1:11001,54010,60621 项目2:11001,60621 第3项:60621
我想创建一个如下所示的新数组:
路线1:11001,11001,60621 路线2:11001,60621,60621 路线3:54010,111001,60621
等 - 直到6号公路。
建议?
----------------------有没有办法在不使用Linq的情况下实现这一目标? VB.net和Linq没有合在一起:))
答案 0 :(得分:18)
听起来你想要Eric Lippert's blog post写这个函数来回复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}));
}
那会让你编写这样的代码:
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, 11001, 60621 54010, 60621, 60621 60621, 11001, 60621 60621, 60621, 60621
编辑:这是VB.NET版本(在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
当然,如果你不想要任何LINQ,这里是一个完全无LINQ的递归实现:
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();
}
}
它不会以与第一个函数相同的顺序返回项目,但在功能上相同。如果您不喜欢LINQ 或递归,那么这里只有一个LINQ-less方法与递归版本完全相同:
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;
}
答案 1 :(得分:3)
您可以使用linq:
var item1 = new[] { 11001, 54010, 60621 };
var item2 = new[] { 11001, 60621 };
var item3 = new [] { 60621 };
IEnumerable<int[]> cartesian =
from i1 in item1
from i2 in item2
from i3 in item3
select new[] { i1, i2, i3 };
答案 2 :(得分:0)
您要做的是生成数组中每个项目的组合。
以下是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 案件。