如何使用Ruby交换矩阵中的列和行

时间:2013-10-08 01:55:56

标签: ruby arrays matrix

我想做的就是使用matrix[i][j]循环与matrix[j][i]交换while。为什么这不起作用?

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

4 个答案:

答案 0 :(得分:14)

如果您的问题是如何使用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]]

答案 1 :(得分:3)

j = 0循环

中移动i
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没有为每个i循环重置为0,那么除了第一次之外它永远不会进入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

答案 2 :(得分:1)

您可以为此使用并行分配,例如a,b = b,a。作为旁注,在Ruby中很少使用while循环,将您称为新手。类似Ruby的方法是使用timesuptodownto等枚举器,它们可以轻松地提供索引ij作为循环变量。当您将方法存储在Array类中时,您还可以保存自己一遍又一遍地键入matrix,因为您已经在类中。此外,首先编写一个mutator方法(改变原始对象,通常用方法名称末尾的bang !表示),然后再编写一个简单调用重复的变异者。以下是我编写代码的方法:

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不能用作mutator。以下是使用上述代码的方法:

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

答案 3 :(得分:0)

转置m x n矩阵时,列变为行,反之亦然。如果数组的行数和列数不相同,则需要从i迭代到matrix [0] .size,因为每个元素中的列数必须是转置矩阵中的行数。

def my_transpose(matrix)

  new_matrix = []

  i = 0


  while i < matrix[0].size # this will create correct number of rows
    new_matrix[i] = []
    j = 0
    while j < matrix.size
      new_matrix[i] << matrix[j][i]
      j += 1
    end
    i += 1
  end

  return new_matrix
end