结构在2d数组上先运行x vs先运行y

Structure to run x first vs y first on 2d array

本文关键字:运行 vs 2d 数组 结构      更新时间:2023-09-26

我想把一个标志传递给一个函数,该函数通过颜色扫描或行扫描来运行算法:

if run-on-x
  for 1..x
    for 1..y
      do something with ary[x][y]
else
  for 1..y
    for 1..x
      do something with ary[x][y]

但是我不想重复所有的循环和逻辑。

我想到了这个:

let numPx = width * height;
for (let px = 0; px < numPx; px++) {
  let [x, y] = yAxis ? [px % width, 0 | px / width] : [0 | px / height, px % height];

但是我认为所有的数学运算都相当繁重,特别是当我在相当大的数组上运行时。

有更好的方法吗?

也许通过简单地传递它们作为参数像这样?:

  function colRowScan(1stAxis,2ndAxis)
      for 1.. 1stAxis
        for 1.. 2ndAxis
          do something with ary[x][y]

没有看到"做某事"是什么,我不知道是否有任何不可预见的原因,为什么这不能工作,但鉴于你发布的它应该做的伎俩。

我不太明白你到底想干什么:

let numPx = width * height;
for (let px = 0; px < numPx; px++) {
  let [x, y] = yAxis ? [px % width, 0 | px / width] : [0 | px / height, px % height];
function f(x, y, on_x) {
    var a, b;
    if (on_x) {
        a = x;
        b = y;
    } 
    else {
        a = y;
        b = x;
    }
    for (var ia = 0; ia < a.length; ia++) {
        for (var ib = 0; ib = b.length; ib++) {
            // ...
        }
    }
}

保留两组内部循环和外部循环,但将内部循环的主体改为单个函数调用。这样就不会有太多的代码重复了。

在您的解决方案中,

let numPx = width * height;
for (let px = 0; px < numPx; px++) {
  let [x, y] = yAxis ? [px % width, 0 | px / width] : [0 | px / height, px % height];

比较次数是numPx次,而之前只有一次,省去了繁重的数学运算。

我认为最简单和最好的解决方案是使用一个单独的函数。

或者你可以试试这个

var a, b, fAry;
if (run-on-x) {
    a = x;
    b = y;
    fAry = ary;
} else {
    a = y;
    b = x;
    fAry = transpose of(ary);  
}
for (var i = 0; i < a; i++) {
    for (var j = 0; j < b; j++) {
        do something with fAry[i][j];
    }
}
  for 1..x
    for 1..y {
      var a = run-on-x ? ary[x][y] : ary[y][x];
      do something with a
    }

为行主要迭代和列主要迭代创建辅助函数,接受数组和应用于数组成员的函数。

var rowMajor = function (a, op) {
    var maxi = a.length;
    var maxj = a[0].length;
    for(var i = 0; i < maxi; ++i) {
        var row = a[i];
        for(var j = 0; j < maxj; ++j) 
            op(row[j],i,j);
            }
};
var colMajor = function (a, op) {
    var maxi = a.length;
    if(maxi === 0) return;
    var maxj = a[0].length;
    for(var j = 0; j < maxj; ++j) {
        for(var i = 0; i < maxi; ++i) {
            op(a[i][j],i,j);
        }
    }
};
// example use (with jQuery)
var array = [[11,12,13],[21,22,23]];
var div = $('<div></div>');
var append =  function(value) { 
    div.append($('<span></span>').text(value + ' '));
};
rowMajor(array,append);
div.append('<br/>');
colMajor(array, append);
$('body').append(div);