从2D阵列获取所有组合

时间:2019-08-05 09:03:47

标签: c# combinations permutation

我有一个二维数组,我想为其获取所有可能的组合。但是我对如何做到这一点感到困惑。我的数据数组如下:

var data = new string[][]
            {
                new string[] {"pa", "ga", "ka"},
                new string[] {"pb", "gb", "kb"}
            };

我的预期输出是这样的:

pa ga ka
pa ga kb
pa gb ka
pa gb kb
pb ga ka
pb ga kb
pb gb ka
pb gb kb

顺序也很重要。例如,我无法将ga pa ka组合在一起。因为第一项需要以p开头,第二项以g开头,第三项以k开头。因此,我不能使用笛卡尔积。

注意:在此示例中,我有两行。我可能还有更多行。

2 个答案:

答案 0 :(得分:1)

可以使用埃里克·利珀特(Eric Lippert)的解决方案,但您需要先转置输入。

这里是转置方法,written by u/recursive

public static IEnumerable<IEnumerable<T>> Transpose<T>(
    IEnumerable<IEnumerable<T>> @this)
{
    var enumerators = @this.Select(t => t.GetEnumerator())
       .Where(e => e.MoveNext());

    while (enumerators.Any())
    {
        yield return enumerators.Select(e => e.Current);
        enumerators = enumerators.Where(e => e.MoveNext());
    }
}

这里是Eric Lippert的组合生成器lifted from here

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(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 })
    );
}

将它们放在一起:

static void Main()
{
    var data = new string[][]
    {
        new string[] {"pa", "ga", "ka"},
        new string[] {"pb", "gb", "kb"}
    };

    var transposed = Transpose(data);

    foreach (var comb in CartesianProduct(transposed))
    {
        Console.WriteLine(string.Join(", ", comb));
    }
}

输出是:

pa, ga, ka
pa, ga, kb
pa, gb, ka
pa, gb, kb
pb, ga, ka
pb, ga, kb
pb, gb, ka
pb, gb, kb

这是您的指定要求。

答案 1 :(得分:0)

var data = new string[][]
        {
            new string[] {"pa", "ga", "ka"},
            new string[] {"pb", "gb", "kb"}
        };
    foreach(var first in data[0])
    {
        foreach(var second in data[1])
        {
            List<string> list = new List<string>(data[1]);
            list.Remove(second);
            var arrayList=list.ToArray();
            string[] myArray = new string[3];
            myArray[0] = first;
            myArray[1] = arrayList[0];
            myArray[2] = arrayList[1];
            Console.WriteLine("{0}", string.Join(" ", myArray));            
        }
    }