【问题标题】:How to get max/min of list of 2d array in c#如何在c#中获取二维数组列表的最大值/最小值
【发布时间】:2016-03-14 21:47:06
【问题描述】:

我有一个这样的二维数组列表:

    static void Main(string[] args) {
        List<int[,]> kidsL = new List<int[,]>();
        int[,] square1 = new int[8, 8];
        int[,] square2 = new int[8, 8];
        int[,] square3 = new int[8, 8];
        for (int i = 0; i < 8; i++)
            for (int j = 0; j < 8; j++) {
                square1[i, j] = 1;
                square2[i, j] = 2;
                square3[i, j] = 3;
            }
        kidsL.Add(square1);
        kidsL.Add(square2);
        kidsL.Add(square3);
        Console.WriteLine();
        Console.Read();
    }

我想确定每个数组的总和并找到最大/最小的一个(在这种情况下,最大的一个是 192)。

有没有一种简单的方法可以做到这一点,还是我只需要循环使用老式的方法?

【问题讨论】:

    标签: c# arrays list


    【解决方案1】:

    嗯,你可以使用下面的代码从int[,]获取IEnumarable&lt;int&gt;

    var enumarable = from int item in square2
                     select item;
    

    此外,您可以使用Cast&lt;int&gt;() 方法将int[,] 解包为IEnumarable&lt;int&gt;

    然后你可以使用Max()Min() linq 方法。

    var min = kidsL.Min(x => (from int item in x select item).Sum());
    var max = kidsL.Max(x => (from int item in x select item).Sum());
    // or
    var min = kidsL.Min(x => x.Cast<int>().Sum())
    

    var Max = (from int[,] array in kidsL
               select (from int item in array select item).Sum())
              .Max();
    

    更新

    from int[,] array in kidsL select (from int item in array select item).Sum() 查询返回一个包含总和的IEnumarable&lt;int&gt;。为了获得最大值的索引,您应该使用ToListToArray() 将 IEnumarable 转换为数组或列表。

    var sumList = (from int[,] array in kidsL
                   select(from int item in array select item).Sum())
                   .ToList();
    
    var maxSum = sumList.Max();
    var maxInd = sumList.IndexOf(maxSum);
    

    sumList 是一个整数列表,包含总和。那么你可以使用Max 方法来获取最大值和IndexOf 来获取最大值的索引。

    【讨论】:

    • 我支持这个答案,这看起来很简单。但是执行速度较慢,因为您必须访问 IEnumerable 并同时使用 Linq。但它比 for 循环更干净。我怀疑是否有比 for 循环更快的方法,因为 IEnumerable 也在 for 循环中执行。
    • @MehrdadKamali 等一下
    • @Valentin 非常感谢,看起来比循环容易得多,但性能有什么变化吗?
    • 还有一件事:如何在方法 2 中获取该数组的索引...例如在本例中 (max=192),列表索引为 2
    • @MehrdadKamali 它不会改变复杂性的渐近行为。您不会看到差异,尤其是对于 8x8 矩阵。
    【解决方案2】:

    Cast&lt;int&gt; 方法会将数组展平为IEnumerable&lt;int&gt;,从而允许使用 LINQ。

    var max = kidsL.Max(square => square.Cast<int>().Sum());
    var min = kidsL.Min(square => square.Cast<int>().Sum());
    

    您还应该注意,如果数组的值和维度很大,可能会发生溢出。

    有没有一种简单的方法可以做到这一点,还是我只需要循环使用老式的方法?

    虽然解决方案很简洁,但它与遍历每个数组的每个元素具有相同的效率。但这确实是一种简单的方法。

    【讨论】:

    • 当我粘贴到我的程序中时,它向我显示了这样的错误:'Queryable.Cast(IQueryable)' 是一种方法,在给定的上下文中无效。顺便说一句,我不是教授。
    • @Mehrdad Kamali,是的,你是对的。修改后查看代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2016-06-21
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    相关资源
    最近更新 更多