数组的笛卡尔积本身具有可变的次数?

问题描述

我想编写一个函数,该函数以可变次数返回数组的笛卡尔积。

现在,如果在编译时已知笛卡尔积的数量,那么我可以执行以下操作(对于3个笛卡尔积):

public static void Main(string[] args)
        {
            int[] numSet = {1,2,3,4};
                        
            var cartesianProduct = from letter in numSet
                                   from number in numSet
                                   from colour in numSet
                                   select new { num1,num2,num3};
        }

现在,我已经看到了这个答案:https://stackoverflow.com/a/4073806/5859885,它似乎提供了一种处理可变数量的集合的方法方法如下:

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

现在,我将其应用于以下问题(这适用于4个笛卡尔乘积(请参见for循环),但是可以很容易地用可变数量笛卡尔乘积的方法包装))

static void Main(string[] args)
        {

            int[] numSet= new int[] { 1,4};
            List<int[]> numList = new List<int[]>();
            for(int i=0; i<4; i++)
            {
                numList.Add(numSet);
            }

            IEnumerable<IEnumerable<int>> combArray = CartesianProduct(numList);
            foreach(var combo in combArray)
            {
                Console.WriteLine(combo);
            }

        }

现在,它可以编译,但是对于for循环的每个迭代(而不是笛卡尔积),我只是得到以下输出System.Linq.Enumerable+ConcatNIterator'1[system.int32]

这是怎么回事?

解决方法

修改方法以将每个组合作为数组返回:

static 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 }).ToArray());
}

然后将最终的返回值转换为数组数组:

var combArray = CartesianProduct(numList).ToArray();

注意:通常,动态构建时使用List<int>代替int[]效率更高,这也取决于您处理答案的方式,IEnumerable<IEnumerable<int>>可能是更好的形式,或者是IEnumerable<int[]>而不是数组数组。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...