在新列表中将2个或多个数组连接成唯一的组合

本文关键字:数组 连接 组合 唯一 2个 新列表 列表 | 更新日期: 2023-09-27 18:09:12

我正在研究一个问题,我可以有2个或更多的字符串值数组。

从第一个数组开始,我需要取每个值并连接下一个数组的第一个值和第三个数组的第一个值,以此类推,直到所有可能的组合都被组合。

的例子:

Array1 {'A', 'B'}
Array2 {'C', 'D', 'E'}
Array3 {'F', 'G', 'H'}

输出将是

Row 1 = A, C, F
Row 2 = A, C, G
Row 3 = A, C, H
Row 4 = A, D, F
Row 5 = A, D, G
Row 6 = A, D, H

等等,直到完成所有的组合。在这种情况下,它将是18个组合。

我以前使用过字符串连接来组合值,但从来没有在这样的过程中,数组的数量和其中的项目数量可以改变,以产生这种类型的输出。

在新列表中将2个或多个数组连接成唯一的组合

答案如下

List<string[]> lists = new List<string[]>()
{
    new[]{"A", "B"},
    new[]{"C", "D", "E"},
    new[]{"F", "G", "H"}
};
var cp = lists.CartesianProduct();
foreach(var line in cp)
{
    Console.WriteLine(String.Join(" ",line));
}

public static partial class MyExtensions
{
    //http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        // base case: 
        IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
        foreach (var sequence in sequences)
        {
            var s = sequence; // don't close over the loop variable 
            // recursive case: use SelectMany to build the new product out of the old one 
            result =
                from seq in result
                from item in s
                select seq.Concat(new[] { item });
        }
        return result;
    }
}

嵌套for循环就可以了:

for (int i=0;i<=Array1.Length;i++)
{
  for (int j=0; j<=Array2.Length; j++)
  {
    for (int k=0;k<=Array3.Length; k++)
      //output however Array1[i] + ", " + Array2[j] + ", " + Array3[k];
  }
}

你可以使用笛卡尔积算法列出所有的组合:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CartesianProduct
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] array1 = new char[] { 'A', 'B' };
            char[] array2 = new char[] { 'C', 'D', 'E' };
            char[] array3 = new char[] { 'F', 'G', 'H' };
            int iterations = array1.Length * array2.Length * array3.Length;
            for (int i = 0; i < iterations; i++)
            {
                Console.WriteLine("{0}, {1}, {2}", array1[i % array1.Length], array2[i % array2.Length], array3[i % array3.Length]);
            }
            Console.WriteLine("Total iterations: " + iterations.ToString());
            Console.Read();
        }
    }
}