Ruby的新手,目前正在学习。
我不确定我是否应该使用数组或矩阵。
我有阵列
[['J','O','I','J','O'],
['I','J','O','J','O'],
['I','I','J','I','J']]
我想在图片中看到以下内容。
['J', 'O']
['I', 'J']
我认为使用Ruby Matrix,但我不确定是否可以将原始数组/矩阵划分为2 x 2的小块,如果它与[J, O], [I, J]
匹配。
或者我应该使用数组和循环。
我感谢任何投入。
答案 0 :(得分:1)
您可以定义以下内容:
def find_in_matrix(matrix, target)
(0..matrix.length-target.length).to_a.product(
(0..matrix.first.length-target.first.length).to_a).select do |x, y|
(0...target.length).to_a.product(
(0...target.first.length).to_a).all? do |test_x, test_y|
matrix[x+test_x][y+test_y] == target[test_x][test_y]
end
end
end
matrix = [["J", "O", "I", "J", "O"],
["I", "J", "O", "J", "O"],
["I", "I", "J", "I", "J"]]
target = [["J", "O"],
["I", "J"]]
find_in_matrix(matrix, target)
=> [[0, 0], [1, 1], [1, 3]]
此解决方案简单地覆盖了matrix
的{{1}}大小的所有子矩阵,并选择与其相等的子矩阵。
答案 1 :(得分:1)
不是直接回答问题,也不是获得匹配位置的有效方法:
matrix = [
%w(J O I J O),
%w(I J O J O),
%w(I I J I J)
]
target = [
%w(J O),
%w(I J)
]
matrix.each_cons(target.length).each_with_index do |sub, row|
sub.map{|a| a.each_cons(target[0].length).to_a}.tap do |sub|
head = sub.shift
head.zip(*sub).each_with_index do |m, col|
if m == target
puts "#{row}, #{col}"
end
end
end
end
答案 2 :(得分:1)
我建议您使用Matrix#minor方法执行此操作。
<强>代码强>
require 'matrix'
def find_in_matrix(arr,sub)
sub_nrows = sub.size
sub_ncols = sub.first.size
rows = Array[*0..arr.size-sub_nrows]
cols = Array[*0..arr.first.size-sub_ncols]
arr_m = Matrix[*arr]
sub_m = Matrix[*sub]
rows.product(cols).select {|i,j| arr_m.minor(i,sub_nrows,j,sub_ncols)==sub_m}
end
示例强>
arr = [['J','O','I','J','O'],
['I','J','O','J','O'],
['I','I','J','I','J']]
sub = [['J', 'O'],
['I', 'J']]
find_in_matrix(arr,sub) #=> [[0, 0], [1, 1], [1, 3]]
find_in_matrix(arr, [['O'], ['J']]) #=> [[0, 1], [1, 2], [1, 4]]
find_in_matrix(arr, [['O']]) #=> [[0, 1], [0, 4], [1, 2], [1, 4]]
find_in_matrix(arr, [['I','J','O']]) #=> [[0, 2], [1, 0]]
find_in_matrix(arr, [['I','J'],['J','O']]) #=> []
find_in_matrix(arr, [[]]) #=> [[0, 0], [0, 1],...,[0, 5]]
# [1, 0], [1, 1],...,[1, 5]]
# [2, 0], [2, 1],...,[2, 5]]
<强>解释强>
对于上面的示例:
sub_nrows = sub.size #=> 2
sub_ncols = sub.first.size #=> 2
rows = Array[*0..(arr.size-sub_nrows)] #=> [0, 1]
cols = Array[*0..(arr.first.size-sub_ncols)] #=> [0, 1, 2, 3]
arr_m = Matrix[*arr]
#=> Matrix[["J", "O", "I", "J", "O"], ["I", "J", "O", "J", "O"],
# ["I", "I", "J", "I", "J"]]
sub_m = Matrix[*sub]
#=> Matrix[["J", "O"], ["I", "J"]]
a = rows.product(cols)
#=> [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3]]
a.select {|i,j| arr_m.minor(i,sub_nrows,j,sub_ncols)==sub_m}
#=> [[0, 0], [1, 1], [1, 3]]
考虑a
select
传递到块中的第一个元素:[0, 0]
(即,块变量i
和j
都被分配了值零)。因此,我们计算:
arr_m.minor(i,sub_nrows,j,sub_ncols) #=> arr_m.minor(0,2,0,2)
#=> Matrix[["J", "O"], ["I", "J"]]
作为
arr_m.minor(0,2,0,2) == sub_m
[0, 0]
已被选中。另一方面,对于[1, 2]
的元素a
,i => 1, j => 2
,所以:
arr_m.minor(i,sub_nrows,j,sub_ncols) #=> arr_m.minor(1,2,2,2)
#=> Matrix[["O", "J"], ["J", "I"]]
不等于sub_m
,因此未选择元素[1, 2]
。
请注意,Matrix#minor
有两种形式。我使用了带有四个参数的表单。另一种形式将两个范围作为参数。