Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby NxM矩阵遍历_Ruby_Matrix_Traversal - Fatal编程技术网

Ruby NxM矩阵遍历

Ruby NxM矩阵遍历,ruby,matrix,traversal,Ruby,Matrix,Traversal,我正在努力解决以下问题的算法: 给定一个只有两个可能值“X”和“O”的矩形矩阵。 值“X”总是以矩形孤岛的形式出现,这些孤岛 始终由至少一行“O”分隔行和列。 计算给定矩阵中的孤岛数 我已经生成了一个解决方案,但是我的循环并没有贯穿整个矩阵。我尝试在I循环中将j初始化为0,但这会引发错误。我对这个主题还不熟悉,我真的想试着理解为什么我的代码不起作用 def matrix(input) row = input.length col = input[0].length counter = 0 i =

我正在努力解决以下问题的算法:

给定一个只有两个可能值“X”和“O”的矩形矩阵。 值“X”总是以矩形孤岛的形式出现,这些孤岛 始终由至少一行“O”分隔行和列。 计算给定矩阵中的孤岛数

我已经生成了一个解决方案,但是我的循环并没有贯穿整个矩阵。我尝试在I循环中将j初始化为0,但这会引发错误。我对这个主题还不熟悉,我真的想试着理解为什么我的代码不起作用

def matrix(input)
row = input.length
col = input[0].length
counter = 0
i = 0
j = 0
while i < row do 
  while j < col do 
  if input[i][j] == "X"
    if i == 0 || input[i-1][j] == "O" && j = 0 || input[i][j-1] == "O"
      counter += 1
    end 
  end 
  j += 1
 end
i += 1
end
  p counter
end 

matrix(
[
  ["X", "X", "O", "X"],
  ["X", "X", "O", "X"],
  ["O", "O", "X", "O"],
  ["O", "O", "X", "O"],
  ["O", "O", "O", "X"],
  ["O", "O", "O", "X"]
]
)
# expected output is 4
def矩阵(输入)
行=input.length
col=输入[0]。长度
计数器=0
i=0
j=0
当我做的时候
而j

这不是家庭作业。我正在练习数据结构和算法。原始问题可以在算法中找到

我们得到一个称为“行”的大小相等的数组
input
。问题中给出的例子如下

input = [
  ["X", "X", "O", "X"],
  ["X", "X", "O", "X"],
  ["O", "O", "X", "O"],
  ["O", "O", "X", "O"],
  ["O", "O", "O", "X"],
  ["O", "O", "O", "X"]
]
为了方便起见,我将元素
input[3][2]#=>“X”
称为行
3
和列
2
中的元素(尽管Ruby没有二维数组或具有行和列的数组的概念)

第一步是构造一个数组
groups
,每个元素(一个“组”)由一个元素组成,其中一行的索引为“X”:

groups
  #=> [[[0, 0]], [[0, 1]], [[0, 3]], [[1, 0]], [[1, 1]], [[1, 3]],
  #    [[2, 2]], [[3, 2]], [[4, 3]], [[5, 3]]] 

我们现在考虑<代码>组的<元素/代码>的最后一个元素(<代码> [5, 3 ] ] /代码>,并询问它的任何元素(只有一个,<代码>(5, 3)< /代码>)与任何其他组中的元素在同一个岛上。我们发现它与组

[[4,3]]
中的
[4,3]
位于同一个岛上(因为元素位于同一列,相隔一行)。因此,我们删除最后一个组,并将其所有元素(此处仅为一个)添加到组
[[4,3]]
。我们现在有:

groups
  #=> [[[0, 0]], [[0, 1]], [[0, 3]], [[1, 0]], [[1, 1]], [[1, 3]],
  #    [[2, 2]], [[3, 2]], [[4, 3], [5, 3]]] 
我们现在用现在的最后一组重复这个过程,
[[4,3],[5,3]]
。我们必须确定该组中的任何一个元素是否与其他组中的任何元素位于同一个岛上。他们不是1。因此,我们确定了第一个岛屿,由位置
[4,3]
[5,3]
组成

初始化
孤岛=[]
后,我们执行以下操作:

islands << groups.pop
我们继续这样做,直到
为空,此时
孤岛
的每个元素都是一个孤岛

代码

def find_islands(input)
  groups = input.each_with_index.with_object([]) { |(row,i),groups|
    row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' } }
  islands = []
  while groups.any?
    last_group = groups.pop
    idx = groups.each_index.find { |idx| same_island?(groups[idx], last_group) }
    if idx.nil?
      islands << last_group
    else
      groups[idx] += last_group
    end
  end
  islands.map(&:sort)
end

def same_island?(group1, group2)
  group1.product(group2).any? { |(i1,j1),(i2,j2)|
  ((i1==i2) && (j1-j2).abs == 1) || ((j1==j2) && (i1-i2).abs == 1) }
end
解释

不可否认,对于一个没有经验的rubest来说,要了解我所介绍的两种方法的工作原理有很多。需要熟悉以下方法:

  • 在模块中:
    每个带有索引的单元
    任何?
    查找
    地图
    产品
  • 类中:
    每个索引
    带对象
    下一个
  • 课堂上:
    pop
    sort
  • 课堂上:
    abs
  • 在模块中:
    nil?
    (记录在)2中
组的初始计算

如果这是一个单独的方法(不是一个坏主意),我们将编写以下内容

def construct_initial_groups(input)
  input.each_with_index.with_object([]) { |(row,i),groups|
    row.each_with_index { |c,`j| groups << [[i,j]] if c == 'X' } }
end
接下来,我们使用带有_object
的方法
枚举器#来获得上面的
构造_初始_组
的第一种形式

编写块变量(
|(行,i),组|
)可能仍然令人困惑。你会知道的

enum = input.each_with_index.with_object([])
  #=> #<Enumerator: #<Enumerator: [["X", "X", "O", "X"], ["X", "X", "O", "X"],
  #     ["O", "O", "X", "O"], ["O", "O", "X", "O"], ["O", "O", "O", "X"],
  #     ["O", "O", "O", "X"]]:each_with_index>:with_object([])>
Ruby使用消歧或分解为三个块变量中的每一个赋值:

row
  #=> ["X", "X", "O", "X"]
i #=> 0
groups
  #=> []
然后执行块计算

row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=> ["X", "X", "O", "X"].each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=>  ["X", "X", "O", "X"]
现在生成
enum
的第二个元素,并将其传递给块,然后执行块计算

(row,i), groups = enum.next
  #=> [[["O", "O", "X", "O"], 2], [[[1, 0]], [[1, 1]], [[1, 3]]]]
row
  #=> ["O", "O", "X", "O"]
i #=> 2
groups
  #=> [[[1, 0]], [[1, 1]], [[1, 3]]]
row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=> ["O", "O", "X", "O"]
其余的计算是类似的

同一个岛?方法

假设

group1 #=> [[0, 0], [1, 0]]
group2 #=> [[0, 1], [1, 1]]
这告诉我们,
[0,0]
[1,0]
在同一个岛上,
[0,1]
[1,1]
在同一个岛上,但我们还不知道这四个坐标是否都在同一个岛上。为了确定是否是这种情况,我们将查看所有坐标对,其中一个来自
group1
,另一个来自
group2
。如果我们将
[0,0]
[1,1]
进行比较,我们不能断定它们位于同一个岛(或不同的岛)上。但是,当我们比较
[0,0]
[0,1]
时,我们看到它们位于同一个岛上(因为它们位于相邻列中的同一行),因此我们推断这两个组的所有元素都位于同一个岛上。例如,我们可以将坐标从
group2
移动到
group1
,并将
group2
从进一步考虑中删除

现在考虑这两个组的方法<代码> SAMEL岛> <代码>所执行的步骤。< /P>

group1 = [[0, 0], [1, 0]]
group2 = [[0, 1], [1, 1]]

a = group1.product(group2)
  #=> [[[0, 0], [0, 1]], [[0, 0], [1, 1]], [[1, 0], [0, 1]],
  #    [[1, 0], [1, 1]]]

(i1,j1),(i2,j2) = a.first
   #=> [[0, 0], [0, 1]]
i1 #=> 0
j1 #=> 0
i2 #=> 0
j2 #=> 1
b = i1==i2 && (j1-j2).abs == 1
   #=> true
c = j1==j2 && (i1-i2).abs == 1
   #=> false
b || c
   #=> true
已发现所考虑的第一对坐标位于同一个岛上。(事实上,
c
的计算不会执行,因为
b
被发现为
true

find_岛
评论

为了说明所有内容是如何组合在一起的,我将在方法
find_islands
中添加注释

def find_islands(input)
  groups = input.each_with_index.with_object([]) { |(row,i),groups|
    row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' } }
  islands = []
  # the following is the same as: until groups.empty?
  while groups.any?
    # pop removes and returns last element of `groups`. `groups` is modified    
    last_group = groups.pop
    # iterate over indices of `groups` looking for one whose members
    # are on the same island as last_group 
    idx = groups.each_index.find { |idx| same_island?(groups[idx], last_group) }
    if idx.nil?
      # last_group is an island, so append it to islands
      islands << last_group
    else
      # groups[idx] members are found to be on the same island as last_group,
      # so add last_group to group groups[idx]
      groups[idx] += last_group
    end
  end
  # sort coordinates in each island, to improve presentation 
  islands.map(&:sort)
end
def find_岛(输入)
groups=输入。每个_带有_索引。带有_对象([]){|(行,i),组|

row.each_与_索引{c,j |组算法

我们得到了一个称为“行”的大小相等的数组
输入

row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=> ["X", "X", "O", "X"].each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=>  ["X", "X", "O", "X"]
groups
  #=> [[[1, 0]], [[1, 1]], [[1, 3]]]
(row,i), groups = enum.next
  #=> [[["O", "O", "X", "O"], 2], [[[1, 0]], [[1, 1]], [[1, 3]]]]
row
  #=> ["O", "O", "X", "O"]
i #=> 2
groups
  #=> [[[1, 0]], [[1, 1]], [[1, 3]]]
row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' }
  #=> ["O", "O", "X", "O"]
groups
  #=> [[[1, 0]], [[1, 1]],
  #    [[1, 3]], [[2, 2]]]
group1 #=> [[0, 0], [1, 0]]
group2 #=> [[0, 1], [1, 1]]
group1 = [[0, 0], [1, 0]]
group2 = [[0, 1], [1, 1]]

a = group1.product(group2)
  #=> [[[0, 0], [0, 1]], [[0, 0], [1, 1]], [[1, 0], [0, 1]],
  #    [[1, 0], [1, 1]]]

(i1,j1),(i2,j2) = a.first
   #=> [[0, 0], [0, 1]]
i1 #=> 0
j1 #=> 0
i2 #=> 0
j2 #=> 1
b = i1==i2 && (j1-j2).abs == 1
   #=> true
c = j1==j2 && (i1-i2).abs == 1
   #=> false
b || c
   #=> true
def find_islands(input)
  groups = input.each_with_index.with_object([]) { |(row,i),groups|
    row.each_with_index { |c,j| groups << [[i,j]] if c == 'X' } }
  islands = []
  # the following is the same as: until groups.empty?
  while groups.any?
    # pop removes and returns last element of `groups`. `groups` is modified    
    last_group = groups.pop
    # iterate over indices of `groups` looking for one whose members
    # are on the same island as last_group 
    idx = groups.each_index.find { |idx| same_island?(groups[idx], last_group) }
    if idx.nil?
      # last_group is an island, so append it to islands
      islands << last_group
    else
      # groups[idx] members are found to be on the same island as last_group,
      # so add last_group to group groups[idx]
      groups[idx] += last_group
    end
  end
  # sort coordinates in each island, to improve presentation 
  islands.map(&:sort)
end