2015-08-27 209 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

這隻適用於如果它是一個方陣:) –