2016-04-17 81 views
1

我是初學者,通過一些練習工作。我試圖操縱的2維陣列,使得如果一個元素是1,則周圍的非對角元素應改爲1:更改數組元素的周邊元素

[[0,0,0,0], 
[0,0,1,0], 
[0,0,0,0], 
[0,0,0,0]] 

應返回

[[0,0,1,0], 
[0,1,1,1], 
[0,0,1,0], 
[0,0,0,0]] 

我使用嵌套的each_with_index時遇到了問題:在我調整左右周圍的初始更改後,由於方法迭代,它會在早期調整時進行拾取並進行不必要的更改。此外,應改變「底」元素的行拋出一個錯誤:

a = [[0,0,0,0], 
    [0,0,1,0], 
    [0,0,0,0], 
    [0,0,0,0] 
    ] 

a.each_with_index do |m, n| # n == index of main array 
    m.each_with_index do |x, y| # y == index of subarray 
     if x == 1 
      a[n][y+1] = 1 unless (a[n][y+1]).nil? #right 
      a[n][y-1] = 1 unless (a[n][y-1]).nil? #left 
      a[n-1][y] = 1 unless (a[n-1][y]).nil? #top 
      a[n+1][y] = 1 unless (a[n+1][y]).nil? #bottom--currently giving an error 
     end 
    end 
end 

任何建議,我怎麼能去解決這兩個方面將備受矚目。

+0

什麼有害的變化?詳細說明。什麼錯誤? – sawa

回答

1

我建議你使用Matrix類。

require 'matrix' 

m = Matrix[*a] 
    #=> Matrix[[0, 0, 0, 0], 
    #   [0, 0, 1, 0], 
    #   [0, 0, 0, 0], 
    #   [0, 0, 0, 0]] 
row, col = m.index(1) 
    #=> [1, 2] 
Matrix.build(m.row_size, m.column_size) { |r,c| 
    (c-col).abs + (r-row).abs <= 1 ? 1 : 0 }.to_a 
    #=> [[0, 0, 1, 0], 
    # [0, 1, 1, 1], 
    # [0, 0, 1, 0], 
    # [0, 0, 0, 0]] 

的此非矩陣版本(其使用方法Array#indexFixnum#divmodArray::newEnumerable#each_slice,以及其他幾個)如下。

nrows, ncols = a.size, a.first.size 
    #=> [4, 4] 
row, col = a.flatten.index(1).divmod(ncols) 
    #=> [1, 2] 
Array.new(nrows*ncols) do |i| 
    r, c = i.divmod(ncols) 
    (c-col).abs + (r-row).abs <= 1 ? 1 : 0 
end.each_slice(ncols).to_a 
    #=> [[0, 0, 1, 0], 
    # [0, 1, 1, 1], 
    # [0, 0, 1, 0], 
    # [0, 0, 0, 0]] 

我發現使用Matrix類是比較容易理解,但它可能沒有有效的方法。

3

爲了避免干擾上一步,您可以(深)複製數組並將參考數組與修改數據分開,或者在修改數組之前提取所有相關索引。後者更好。此外,使用扁平數組比處理嵌套數組要容易得多,所以我將把a轉換成扁平數組b,並在b內工作。

b = a.flatten 

b 
.each_index.select{|i| b[i] == 1} 
.each do 
    |i| 
    b[i - 1] = 1 if b[i - 1] and i - 1 >= 0 
    b[i + 1] = 1 if b[i + 1] 
    b[i - 4] = 1 if b[i - 4] and i - 4 >= 0 
    b[i + 4] = 1 if b[i + 4] 
end 

a = b.each_slice(4).to_a 
# => [[0, 0, 1, 0], [0, 1, 1, 1], [0, 0, 1, 0], [0, 0, 0, 0]] 
+1

b [i-1]和b [i-4]上的檢查只會從數組的末尾返回第一/第四,這不是我想要的。 –

+0

@FrederickCheung這是我的錯誤。感謝您指出。 – sawa