【问题标题】:Loop through array to the Cartesian power n遍历数组到笛卡尔幂 n
【发布时间】:2018-07-06 16:57:31
【问题描述】:

我想遍历数组,它是数组到笛卡尔幂 n 的结果。 https://en.wikipedia.org/wiki/Cartesian_product#n-ary_product

这就是我想要达到的,只是有n个深度:

int[] array = new int[] { 5, -4, ... }
foreach(int a in array) {
    foreach(int b in array) {
        foreach(int c in array) {
           ...
           int[] NewArray = new int[] { a, b, c, ... }

在 Python 中,这相当于:

from itertools import product
for (NewArray in product(array, repeat=n)):
    print(NewArray)

我不知道如何在 C# 中实现这一点。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 你可以尝试递归解决。
  • Enumerable.Repeat(array, n).Aggregate((IEnumerable<int[]>)new[] {new int[0]}, (a, b) => a.SelectMany(c => b, (d, e) => { var f = new int[d.Length + 1]; d.CopyTo(f, 0); f[d.Length] = e; return f; }))

标签: c# arrays cartesian-product


【解决方案1】:

你可以用一点数学和yield return实现一个笛卡尔积:

static public IEnumerable<T[]> Product<T>(IList<T> items, int repeat) {
    var total = (int)Math.Pow(items.Count, repeat);
    var res = new T[repeat];
    for (var i = 0 ; i != total ; i++) {
        var n = i;
        for (var j = repeat-1 ; j >= 0 ; j--) {
            res[j] = items[n % items.Count];
            n /= items.Count;
        }
        yield return res;
    }
}

这样称呼

foreach (var arr in Product(new[] {"quick", "brown", "fox"}, 3)) {
    Console.WriteLine(string.Join("-", arr));
}

产生以下输出:

quick-quick-quick
quick-quick-brown
quick-quick-fox
quick-brown-quick
quick-brown-brown
quick-brown-fox
quick-fox-quick
quick-fox-brown
quick-fox-fox
brown-quick-quick
brown-quick-brown
brown-quick-fox
brown-brown-quick
brown-brown-brown
brown-brown-fox
brown-fox-quick
brown-fox-brown
brown-fox-fox
fox-quick-quick
fox-quick-brown
fox-quick-fox
fox-brown-quick
fox-brown-brown
fox-brown-fox
fox-fox-quick
fox-fox-brown
fox-fox-fox

Demo.

【讨论】:

    【解决方案2】:

    您可以计算两个数组的笛卡尔积,如下所示

        string[][] CartesianProduct(string[] arr1, string[] arr2)
        {
            // for each s1 in arr1, extract arr2, 
            // then pass s1 and s2 into a newly-made string array.
            return arr1.SelectMany(s1 => arr2, (s1, s2) => new string[] { s1, s2 })
                .ToArray();
        }
    

    假设你有两个数组,即

        string[] set1 = new string[] { "a", "b", "c" };
        string[] set2 = new string[] { "x", "y", "z" };
    

    调用 CartesianProduct 函数,该函数将返回如下结果值。

       var cartesionProduct = CartesianProduct (set1,set2);
    

    【讨论】:

    • 这不能回答问题。这不是求两个数组的笛卡尔积,而是求任意数量数组的乘积。
    猜你喜欢
    • 2011-02-08
    • 2011-01-31
    • 2019-03-31
    • 2012-05-07
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多