嵌套列表 C# 的对角线差异

Diagonal difference of a nested List C#

我试图从一个函数中获取嵌套列表绝对差异。我有一个固定的矩阵,我想在不固定的时候得到 result 。目前我有一个 3 x 3 矩阵,这是我试过的:

List<List<int>> matrix = new List<List<int>> { 
    new List<int>() { 6, 2, 3 },
    new List<int>() { 1, 8, 2 },
    new List<int>() { 3, 4, 7 }
};

public static int diagonalDifference(List<List<int>> arr)
{
   int right = 0;
   int left = 0;
   int result = 0;

   for (int i = 0; i < arr.Count; i++)
   {
       for (int j = 0; j < arr.Count; j++)
       {
           right = arr[0][0] + arr[1][1] + arr[2][2];
           left = arr[2][0] + arr[1][1] + arr[0][2];
       }

       result = Math.Abs(right - left);  
   }

   return result;
}

//Output : 7

那么,如何调整函数以获得与 动态矩阵 的绝对差异? 感谢指导和帮助!!

您可以执行类似以下操作:

    static void Main(string[] args)
    {
        List<List<int>> matrix = new List<List<int>> {
                                        new List<int>(){ 6, 2, 3,4 },
                                        new List<int>(){ 1, 8, 2,7 },
                                        new List<int>(){ 3, 4, 7 ,10},
                                        new List<int>(){ 13, 24, 4 ,8}, //added one more to demo the code
                                 };

        var diagnoalValues = Enumerable.Range(0, matrix.Count).Select(x => new
        {
            Left = matrix[x][x], 
            Right = matrix[matrix.Count - x - 1][x]
        }).ToList();

        var leftSum = diagnoalValues.Sum(x => x.Left);
        var rightRum = diagnoalValues.Sum(x => x.Right);

        var difference = Math.Abs(leftSum - rightRum);

        Console.WriteLine($"Difference:{difference}");
    }

如果你想减少迭代,你也可以改成下面这样:

    static void Main(string[] args)
    {
        List<List<int>> matrix = new List<List<int>> {
            new List<int>(){ 6, 2, 3,4 },
            new List<int>(){ 1, 8, 2,7 },
            new List<int>(){ 3, 4, 7 ,10},
            new List<int>(){ 13, 24, 4 ,8},
        };

        var sum = Enumerable.Range(0, matrix.Count)
            .Aggregate(new { Left = 0, Right = 0 }, (previous, index) => new
            {
                Left = previous.Left + matrix[index][index],
                Right = previous.Right + matrix[matrix.Count - index - 1][index]
            });


        var difference = Math.Abs(sum.Left-sum.Right);

        Console.WriteLine($"Difference:{difference}");
    }

我没有过多更改您的代码就想到了这个。您不需要嵌入 for 循环来实现这一点。该算法从左向右计算左右对角线,其中右对角线从顶部开始向右下降,左对角线从底部开始向右上升。

    public static int diagonalDifference(List<List<int>> arr)
    {
        var right = 0;
        var left = 0;
        var result = 0;
        var rowCount = arr.Count - 1;
        var listCount = arr[0].Count;

        for (var j = 0; j < listCount; j++)
        {
            right += arr[j][j];
            left += arr[rowCount - j][j];
        }
        result = Math.Abs(right - left);

       return result;
    }

这假设矩阵在列和行中是偶数。每行具有相同数量的元素,并且一行中的元素数量等于矩阵的行数。对于不同的列和行,必须对其进行修改以满足您的需要。

动态矩阵的主要挑战是长度与宽度不匹配。在这种情况下,您将必须决定如何处理它(缺失的平均值、跳过缺失等)。

要处理一个相等的矩阵,你只需要矩阵的长度。

下面我将展示如何获取对角线长度以及如何使用 for 循环创建左右对角线。 没有考虑到长度和宽度不相等的情况,相反它会断线,因为对角线长度是两个维度中较小的一个。

var right = 0;
var left = 0;

var length = matrix.Count;
var width = matrix[0].Count;

var diagLength = length == width ? length : Math.Min(length, width);

for (int i = 0; i < diagLength; i++)
{
    right += matrix[i][i];
    left += matrix[diagLength - 1 - i][i];
}

var diff = Math.Abs(right - left);

通常,当我们遇到此类问题时,我们可以 查询 借助 Linq:

using System.Linq;

...

private static diagonalDifference(List<List<int>> arr) => Math.Abs(arr
  .Select((line, index) => line[index] - line[line.Count - 1 - index])
  .Sum());

如果您更喜欢旧的 for 循环(请注意,我们只需要 一个 循环):

private static diagonalDifference(List<List<int>> arr) {
  int result = 0;

  for (int i = 0; i < arr.Count; ++i) 
    result += arr[i][i] - arr[i][arr.Count - 1 - i];
 
  return Math.Abs(result); 
}

这是怎么回事?我们逐行扫描矩阵 (arr) line 求和左右对角线项之间的差异:

6, 2, 3  -> 6 - 3 == 3 
1, 8, 2     8 - 8 == 0
3, 4, 7     7 - 3 == 4
            ----------
                     7 in total