代码
def extract(matrix, row, col)
last_row = matrix.size-1
last_col = matrix.first.size-1
diag_sum = row + col
diag_first_row = diag_sum - [diag_sum, last_col].min
diag_last_row = [last_row, diag_sum].min
ante_diag_diff = row - col
ante_diag_first_row = [ante_diag_diff, 0].max
ante_diag_last_row = ante_diag_diff +
[last_col, last_row - ante_diag_diff].min
arr = []
(0..last_col).each { |j| arr << matrix[row][j] unless j == col }
(0..last_row).each { |i| arr << matrix[i][col] unless i == row }
(diag_first_row..diag_last_row).each do |i|
arr << matrix[i][diag_sum - i] unless i == row
end
(ante_diag_first_row..ante_diag_last_row).each do |i|
arr << matrix[i][i - ante_diag_diff] unless i == row
end
arr
end
示例
matrix = Array.new(5) { Array.new(5) { rand(10..99) } }
#=> [[52, 29, 61, 35, 27],
# [68, 99, 67, 18, 67],
# [79, 10, 73, 15, 36],
# [49, 94, 28, 24, 53],
# [37, 26, 65, 65, 43]]
(0..4).each do |i|
(0..4).each do |j|
puts "#{i}, #{j}: #{extract(matrix,i,j)}"
end
end
i j
----------------------------------------------------------------------
0, 0: [29, 61, 35, 27, 68, 79, 49, 37, 99, 73, 24, 43]
0, 1: [52, 61, 35, 27, 99, 10, 94, 26, 68, 67, 15, 53]
0, 2: [52, 29, 35, 27, 67, 73, 28, 65, 99, 79, 18, 36]
0, 3: [52, 29, 61, 27, 18, 15, 24, 65, 67, 10, 49, 67]
0, 4: [52, 29, 61, 35, 67, 36, 53, 43, 18, 73, 94, 37]
1, 0: [99, 67, 18, 67, 52, 79, 49, 37, 29, 10, 28, 65]
1, 1: [68, 67, 18, 67, 29, 10, 94, 26, 61, 79, 52, 73, 24, 43]
1, 2: [68, 99, 18, 67, 61, 73, 28, 65, 35, 10, 49, 29, 15, 53]
1, 3: [68, 99, 67, 67, 35, 15, 24, 65, 27, 73, 94, 37, 61, 36]
1, 4: [68, 99, 67, 18, 27, 36, 53, 43, 15, 28, 26, 35]
2, 0: [10, 73, 15, 36, 52, 68, 49, 37, 61, 99, 94, 65]
2, 1: [79, 73, 15, 36, 29, 99, 94, 26, 35, 67, 49, 68, 28, 65]
2, 2: [79, 10, 15, 36, 61, 67, 28, 65, 27, 18, 94, 37, 52, 99, 24, 43]
2, 3: [79, 10, 73, 36, 35, 18, 24, 65, 67, 28, 26, 29, 67, 53]
2, 4: [79, 10, 73, 15, 27, 67, 53, 43, 24, 65, 61, 18]
3, 0: [94, 28, 24, 53, 52, 68, 79, 37, 35, 67, 10, 26]
3, 1: [49, 28, 24, 53, 29, 99, 10, 26, 27, 18, 73, 37, 79, 65]
3, 2: [49, 94, 24, 53, 61, 67, 73, 65, 67, 15, 26, 68, 10, 65]
3, 3: [49, 94, 28, 53, 35, 18, 15, 65, 36, 65, 52, 99, 73, 43]
3, 4: [49, 94, 28, 24, 27, 67, 36, 43, 65, 29, 67, 15]
4, 0: [26, 65, 65, 43, 52, 68, 79, 49, 27, 18, 73, 94]
4, 1: [37, 65, 65, 43, 29, 99, 10, 94, 67, 15, 28, 49]
4, 2: [37, 26, 65, 43, 61, 67, 73, 28, 36, 24, 79, 94]
4, 3: [37, 26, 65, 43, 35, 18, 15, 24, 53, 68, 10, 28]
4, 4: [37, 26, 65, 65, 27, 67, 36, 53, 52, 99, 73, 24]
说明
首先观察,如果目标元素在行i和列j中,则通过该点的对角线上的元素[p,q]具有p+q == i+j的属性。类似地,通过该点的前对角线上的元素[p,q] 具有p-q == i-j 的属性
假设
row = 1
col = 2
然后
last_row = matrix.size-1
#=> 4
last_col = matrix.first.size-1
#=> 4
diag_sum = row + col
#=> 3
diag_first_row = diag_sum - [diag_sum, last_col].min
#=> 0
diag_last_row = [last_row, diag_sum].min
#=> 3
ante_diag_diff = row - col
#=> -1
ante_diag_first_row = [ante_diag_diff, 0].max
#=> 0
ante_diag_last_row = ante_diag_diff +
[last_col, last_row - ante_diag_diff].min
#=> 3
剩下的计算很简单。
这是上面的一个变体,它使用的代码更少,效率可能略低。
def extract(matrix, row, col)
row_range = 0..matrix.size-1
col_range = 0..matrix.first.size-1
diag_sum = row + col
ante_diag_diff = row - col
arr = []
col_range.each { |j| arr << matrix[row][j] unless j == col }
row_range.each do |i|
next if i == row
arr << matrix[i][col]
j = diag_sum - i
arr << matrix[i][j] if col_range.cover?(j)
j = i - ante_diag_diff
arr << matrix[i][j] if col_range.cover?(j)
end
arr
end