2015-08-27 145 views
6

上对y首次运行X首先我想有传递到运行的任何山坳扫描或行扫描的算法的功能标志:结构以二维数组

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]; 

但我认为所有的数学是相当沉重的,尤其是当我上运行它相当大的阵列。

有没有更好的方法来做到这一点?

+0

如果这是java的,那么你正在尝试做的可能是在浪费时间。每次进行评估(执行)时,即时编译将尝试进一步优化字节码。最重要的是,它是动态的:如果采用不同的分支,它将改变实现。这意味着如果它看起来更加优化(并且不打破任何依赖),它可以在运行时交换循环。试图智取编译器可能会导致'较慢'的代码,因为优化器只会看到更多潜在的依赖关系被破坏。 – StarShine

+0

@StarShine - 你为什么假设它是java? –

+0

没有假设。只是在使用Java的情况下发表评论。在某种程度上,这个评论也适用于Javascript。早期的浏览器都做了JavaScript的JIT编译,但后来转向了本地代码生成。然而,未来JavaScript编译器的演变可能会包含jit的某些方面,例如在生成本地字节码时重新引入循环优化和分支预测优化。另见http:// creativejs。com/2013/06/the-race-for-speed-part-1-javascript-engine-family-tree/ – StarShine

回答

2

也许通过简单地将它们作为像这样?:

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]; 
+0

当你尝试访问ary [x] [y]时,你如何知道x在1stAxis或2nd轴上? ? – Somabrata

+0

在他的两个例子中,他的格式为ary [x] [y],所以我没有改变它来混淆他,但参数也可以插入到那里。 – IfTrue

+0

我可以猜出这在你的解决方案中:在循环内部访问ary [i] [j]时,我将从第一个循环来,j将从第二个循环来? – Somabrata

1
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++) { 
      // ... 
     } 
    } 
} 
+0

如何从循环内部尝试访问ary [x_i] [y_j]时知道x是在a还是b?如果y在a中,它可能试图访问ary [y_i] [x_j]。 – Somabrata

+0

@Somabrata'a [ia]'或'a [ib]'或相反:'b [ia]'或'b [ib]'。按字母顺序原则。 – Vidul

1

保持两套内环和外环的,但改变内环的身体一个函数调用。然后,没有太多的代码重复。

0

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

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); 
0

在您的解决方案,

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]; 
    } 
} 
1
for 1..x 
    for 1..y { 
     var a = run-on-x ? ary[x][y] : ary[y][x]; 
     do something with a 
    } 
+0

这只适用于如果它是一个方阵:) –