2013-10-08 41 views
2

我想要做的就是使用while循環交換matrix[i][j]matrix[j][i]。爲什麼這不起作用?如何使用Ruby交換矩陣中的列和行

def my_transpose(matrix) 

    new_matrix = [] 

    i = 0 
    j = 0 

    while i < matrix.size 
    new_matrix[i] = [] 
    while j < matrix.size 
     new_matrix[i] << matrix[j][i] 
     j += 1 
    end 
    i += 1 
    end 

    return new_matrix 
end 

如果我喜歡的東西

[ 
[1,2,3], 
[1,2,3], 
[1,2,3] 
] 

它只是返回1,1,1運行此。我如何獲得它返回1,1,1; 2,2,2; 3,3,3

+2

爲什麼不簡單地使用從陣列轉置? – vgoff

+0

FYI Rubinius有一個純Ruby實現:https://github.com/rubinius/rubinius/blob/master/kernel/common/array.rb#L1623 – Stefan

回答

1

i環路內移動j = 0

def my_transpose(matrix) 

    new_matrix = [] 

    i = 0 


    while i < matrix.size 
    new_matrix[i] = [] 
    j = 0 # move this here 
    while j < matrix.size 
     new_matrix[i] << matrix[j][i] 
     j += 1 
    end 
    i += 1 
    end 

    return new_matrix 
end 

如果j沒有重置爲0每i環路,則它不會進入j循環,除了第一次:

i = 0 
j = 0 
# Enter i loop 
new_matrix[0] = [] 
# Enter j loop 
    new_matrix[0] << matrix[0][0] 
    j += 1 #=> 1 

    new_matrix[0] << matrix[1][0] 
    j += 1 #=> 2 

    new_matrix[0] << matrix[2][0] 
    j += 1 #=> 3 
# Exit j loop 
i += 1 #=> 1 

new_matrix[1] = [] 
# Does not enter j loop as j = 3 > matrix.size 
i += 1 #=> 2 

new_matrix[2] = [] 
# Does not enter j loop as j = 3 > matrix.size 
i += 1 #=> 3 
# Exit i loop 
+0

謝謝!你能解釋爲什麼'j = 0'必須移動嗎? – reichertjalex

+1

@punkinbread用更多解釋更新 – tihom

10

如果您問題是如何交換矩陣中的列和行與Ruby,答案是使用內置的Array#transpose

a = [ 
[1,2,3], 
[1,2,3], 
[1,2,3] 
] 
#=> [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 
a.transpose 
#=> [[1, 1, 1], [2, 2, 2], [3, 3, 3]] 
+2

雖然我不想使用它,但我試圖創建自己的。 – reichertjalex

+0

我upvote,因爲這確實是我的問題,這篇文章有很好的谷歌排名 – Xavier

1

您可以對此使用並行分配,例如, a,b = b,a。作爲一個方面說明,while循環在Ruby中很少使用,因此將它視爲一個新手。更類似Ruby的方法是使用像times,upto,downto等的枚舉數,它將很方便地提供指數ij作爲循環變量。當你將這些方法存儲在Array類中時,你可以節省一次又一次地輸入matrix,因爲你已經在課堂上了。此外,首先編寫一個增變器方法(改變原始對象,通常在方法名稱末尾通常用砰砰聲!表示),然後編寫一個額外的非增變器方法,該方法簡單地調用複製器上的增變器。這是我會怎麼寫代碼:

class Array 
    def my_transpose! 
    size.times do |i| 
     0.upto(i) do |j|         # iterate only through lower half 
     self[i][j], self[j][i] = self[j][i], self[i][j] # swap rows and cols 
     end 
    end 
    self             # return the array itself 
    end 

    def my_transpose 
    dup.map(&:dup).my_transpose!       # inner arrays are dup'ed, too 
    end 
end 

有趣的是,Ruby的內置transpose不能作爲賦值函數。以下是如何使用上面的代碼:

a = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 

a.my_transpose!      # mutator 
#=> [[1, 1, 1], [2, 2, 2], [3, 3, 3]] 

a 
#=> [[1, 1, 1], [2, 2, 2], [3, 3, 3]] # note that a changed 

a.my_transpose! 
#=> [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 

a 
#=> [[1, 2, 3], [1, 2, 3], [1, 2, 3]] # a is back to its original state 

a.my_transpose       # non-mutator 
#=> [[1, 1, 1], [2, 2, 2], [3, 3, 3]] 

a 
#=> [[1, 2, 3], [1, 2, 3], [1, 2, 3]] # note that a did not change