遍历二维数组(矩阵)的对角线

5

我发现这个帖子在对角线遍历数组方面非常有用。但是,我在镜像它时遇到了困难。例如:

var m = 3;
var n = 4;
var a = new Array();
var b = 0;

for(var i = 0; i < m; i++) {
  a[i] = new Array(n);
  for(var j = 0; j < n; j++) {
    a[i][j] = b;
      b++;
  }
}

for (var i = 0; i < m + n - 1; i++) {
  var z1 = (i < n) ? 0 : i - n + 1;
  var z2 = (i < m) ? 0 : i - m + 1;
  for (var j = i - z2; j >= z1; j--) {
    console.log(a[j][i - j]);
  }
}

控制台读取[[0],[4,1],[8,5,2],[9,6,3],[10,7],[11]]

我希望它读取[[8],[4,9],[0,5,10],[1,6,11],[2,7],[3]]

已经被困了一段时间,就像魔方一样 >_<


不,我是自学的程序员...已经不在学校了。也许我应该回去:P - jonobr1
2个回答

9

我发现整个z1、z2的逻辑有些晦涩难懂,因此我使用了不同的方式来完成:

var m = 3;
var n = 4;
var a = new Array();
var b = 0;

for(var i = 0; i < m; i++) {
  a[i] = new Array(n);
  for(var j = 0; j < n; j++) {
    a[i][j] = b;
      b++;
  }
}

var out = new Array();
for (var i = 1 - m; i < n; i++) {
    var group = new Array();
    for (var j = 0; j < m; j++) {
        if ((i + j) >= 0 && (i + j) < n) {
            group.push(a[j][i + j]);
        }
    }
    out.push(group);
}
console.log(out);

[[8], [4, 9], [0, 5, 10], [1, 6, 11], [2, 7], [3]]打印到控制台。

工作原理

您的矩阵构造为您提供了一个类似于以下矩形的矩形(其中a数组是行集):

 0  1  2  3
 4  5  6  7
 8  9 10 11

这意味着对角线在此网格上:

 #  #  0  1  2  3
    #  4  5  6  7  #
       8  9 10 11  #  #

现在我们只是在一个倾斜的矩形上循环,它看起来像这样标准化:

 #  #  0  1  2  3
 #  4  5  6  7  #
 8  9 10 11  #  #

现在您会注意到,对于每个添加的行,您都会获得一个额外的列(以#开头),并且第一列现在被这个数量倾斜了(如果您想象保持第一行不变并将下面的行向左滑动)。因此,对于我们的外部for循环(在列上),第一列实际上是旧的第一列0减去行数m1,这给出0-m+11-m。最后一列实际上保持不变,因此我们仍然循环到n。然后只需要取每一列并循环每个m行(内部for循环)。

当然,这会留下一堆undefined(上面网格中的#),但我们可以跳过它们,使用简单的if确保ijmn范围内。

可能比z1/z1版本稍微低效,因为我们现在正在循环冗余的#单元格而不是预先计算它们,但这不应该在现实世界中产生任何差异,而且我认为代码最终更易读。


我同意,这解释得非常清楚。非常感谢! - jonobr1

1
/*
Initialize the 2-D array.
*/      
String array2D[] = { 
                    "mvjlixape",
                    "jhbxeenpp",
                    "hktthbswy",
                    "rwainuyzh",
                    "ppfxrdzkq",
                    "tpnlqoyjy",
                    "anhapfgbg",
                    "hxmshwyly",
                    "ujfjhrsoa" 
                    };
    // Print 2D array diagonally  for left top to right down
            for(int j = 0; j < array2D.length; j ++){
                for(int i = 0; i < array2D.length; i++){
                    if(i+j >= array2D.length)
                        break;
                    System.out.print(array2D[i].charAt(i+j));
                }
                System.out.println();
            }
            for(int j = 1; j < array2D.length; j ++){
                for(int i = 0; i < array2D.length; i++){
                    if(i+j >= array2D.length)
                        break;
                    System.out.print(array2D[i + j].charAt(i));
                }
                System.out.println();
            }

            // Print diagonally right top to left bottom diagonal
            for(int j = 0; j < array2D.length; j++){
                for(int i = j; i >= 0; i--){
                    System.out.print(array2D[j - i].charAt(i));
                }
                System.out.println();
            }
            for(int j = 1; j < array2D.length; j ++){
                for(int i = j; i < array2D.length; i++){
                    System.out.print(array2D[array2D.length - i + j - 1].charAt(i));
                }
                System.out.println();
            }

这里我将打印数组对角线分成了四个部分。 - Jatinderpal Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接