数组的笛卡尔积与自身可变次数?

Posted

技术标签:

【中文标题】数组的笛卡尔积与自身可变次数?【英文标题】:Cartesian product of an array with itself a variable amount of times? 【发布时间】:2021-02-07 05:21:37 【问题描述】:

我想写一个函数,它返回一个数组的笛卡尔积,它自身的次数是可变的。

现在,如果在编译时知道笛卡尔积的数量,那么我可以执行以下操作(对于 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://***.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, 2, 3, 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].

这里发生了什么?

【问题讨论】:

更改写入语句:Console.WriteLine(string.Join(",",combo)); 谢谢!你知道我如何将每个组合存储在一个数组中,然后将所有这些组合存储在一个数组中吗?所以我有一个锯齿状数组(数组数组)? 它们已经在变量 numList 中。它不是锯齿状的,只是一个规则的二维数组,因为宽度总是 4。 【参考方案1】:

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

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&lt;int&gt; 而不是int[] 更有效,这也取决于您处理答案的方式,IEnumerable&lt;IEnumerable&lt;int&gt;&gt; 可能是更好的形式,或者IEnumerable&lt;int[]&gt; 而不是数组数组。

【讨论】:

以上是关于数组的笛卡尔积与自身可变次数?的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 不同的二叉搜索树-笛卡尔积与卡特兰数

查找 JavaScript 数组值的所有组合(笛卡尔积)

powershell 返回数组数组的笛卡尔积

使用 PHP 关联数组查找笛卡尔积

数据库(join) 内连接外连接笛卡尔积

js编写一个数组笛卡尔积算法