Arrays 二维阵列变换

Arrays 二维阵列变换,arrays,ruby,Arrays,Ruby,这是我的阵列: [[0,0,0,0], [0,1,0,0], [0,0,0,1], [0,0,0,0]] 为此,我希望1的正上方、下方、右侧和左侧的“0”单元格也更改为1 预期产出将是: 0100 1111 0111 0001 但是,对于我的代码: class Image def initialize(image) @image = image end def output_image @image.map do |image| puts image.j

这是我的阵列:

[[0,0,0,0],
[0,1,0,0],
[0,0,0,1],
[0,0,0,0]]

为此,我希望1的正上方、下方、右侧和左侧的“0”单元格也更改为1

预期产出将是:

0100
1111
0111
0001

但是,对于我的代码:

class Image
  def initialize(image)
    @image = image
  end

  def output_image
    @image.map do |image|
      puts image.join('')
    end
  end

  def blur
    find_ones.each do |x, y|
      blur_cell x, y
    end
  end

  def find_ones
    ones = []
    @image.each_with_index do |row, y|
      row.each_with_index do |cell, x|
        ones << [x, y] if cell == 1
      end
    end
    ones
  end

  def blur_cell(x, y)
    write_cell x + 1, y, 1
    write_cell x - 1, y, 1
    write_cell x, y + 1, 1
    write_cell x, y - 1, 1
  end

  def write_cell(x, y, value)
    return nil unless y > 0 && y < @image.length
    return nil unless x > 0 && x < @image[0].length
    @image[y][x] = value
  end
end

image = Image.new([
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
])

image.blur
image.output_image
类图像
def初始化(图像)
@图像=图像
结束
def输出图像
@image.map do | image|
放置图像。连接(“”)
结束
结束
def模糊
找到一个。每个都做x,y|
模糊单元x,y
结束
结束
找一个
1=[]
@image.each_与_索引do |行,y|
行。每个带有_索引的|单元格,x|
一个0&&y<@image.length
返回nil,除非x>0&&x<@image[0]。长度
@图像[y][x]=值
结束
结束
image=image.new([
[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 0, 0, 0]
])
图像模糊
image.output\u图像
我得到以下输出:

0000
0111
0111
0001


如果您能帮我指出错误的位置,或提供有关如何修复错误的建议,我们将不胜感激:)

代码中的错误

arr = [
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
]

convert arr
  #=> [[0, 1, 0, 0],
  #    [1, 1, 1, 1],
  #    [0, 1, 1, 1],
  #    [0, 0, 0, 1]]
您的代码有一些小错误。下面是正确的代码。将其与原始代码逐行比较,您将看到错误以及我如何修复它们。我也做了一些简化

class Image
  def initialize(image)
    @image = image
  end

  def output_image
    @image.map do |image|
      puts image.join('')
    end
  end

 def blur
    find_ones.each do |x, y|
      blur_cell x, y
    end
  end

  def find_ones
    ones = []
    @image.each_with_index do |row, x|
      row.each_with_index do |cell, y|
        ones << [x, y] if cell == 1
      end
    end
    ones
  end
建议的备选方案

arr = [
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
]

convert arr
  #=> [[0, 1, 0, 0],
  #    [1, 1, 1, 1],
  #    [0, 1, 1, 1],
  #    [0, 0, 0, 1]]
这是另一种方法

def convert(arr)
  return [] if arr.empty?
  nbr_rows = arr.size
  nbr_cols = arr.first.size
  a = container(arr)
  (1..nbr_rows).
    each_with_object(Array.new(nbr_rows) { Array.new(nbr_cols) }) { |i,b|
      (1..nbr_cols).each { |j|
        b[i-1][j-1] = [a[i][j], a[i][j-1], a[i][j+1], a[i-1][j], a[i+1][j]].max } }
end

def container(arr)
  nbr_rows = arr.size
  nbr_cols = arr.first.size
  Array.new(nbr_rows+2) { |i|
    Array.new(nbr_cols+2) { |j| (i.zero? || i==nbr_rows+1 || j.zero? ||
      j==nbr_cols+1) ? 0 : arr[i-1][j-1] } }
end
示例

arr = [
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
]

convert arr
  #=> [[0, 1, 0, 0],
  #    [1, 1, 1, 1],
  #    [0, 1, 1, 1],
  #    [0, 0, 0, 1]]
解释

首先,请注意,如果元素的上、下、左或右等于1,则等于0的元素被设置为1。对于不在第一行或最后一行或第一列或最后一列中的元素,计算非常简单。处理周界元素的一种方法是构造第二个数组,该数组从原始数组开始,在前后添加一行零,在左右添加一行零。然后对周长行和列以外的所有图元进行计算。最后,剥离第一行和最后一行以及第一列和最后一列。我就是这么做的

对于示例中使用的数组,步骤如下所示。首先考虑方法>代码>容器< /代码> .<
nbr_rows = arr.size
  #=> 4 
nbr_cols = arr.first.size
  #=> 4 
Array.new(nbr_rows+2) { |i|
  Array.new(nbr_cols+2) { |j| (i.zero? || i==nbr_rows+1 || j.zero? ||
    j==nbr_cols+1) ? 0 : arr[i-1][j-1] } }
  #=> Array.new(6) { |i|
  #     Array.new(6) { |j| (i.zero? || i==5 || j.zero? ||
  #       j==5) ? 0 : arr[i-1][j-1] } }
  #=> [[0, 0, 0, 0, 0, 0],
  #    [0, 0, 0, 0, 0, 0],
  #    [0, 0, 1, 0, 0, 0],
  #    [0, 0, 0, 0, 1, 0],
  #    [0, 0, 0, 0, 0, 0],
  #    [0, 0, 0, 0, 0, 0]] 
请注意,此数组夹在两行零和两列零之间

现在,让我们逐步进行
convert

arr.empty?
  #=> false, so we do not return []
nbr_rows = arr.size
  #=> 4 
nbr_cols = arr.first.size
  #=> 4 
a = container(arr)
  #=> [[0, 0, 0, 0, 0, 0],
  #    [0, 0, 0, 0, 0, 0],
  #    [0, 0, 1, 0, 0, 0],
  #    [0, 0, 0, 0, 1, 0],
  #    [0, 0, 0, 0, 0, 0],
  #    [0, 0, 0, 0, 0, 0]]     
(1..nbr_rows).each_with_object(Array.new(nbr_rows) { Array.new(nbr_cols) }) { |i,b|
  (1..nbr_cols).each { |j|
    b[i-1][j-1] = [a[i][j], a[i][j-1], a[i][j+1], a[i-1][j], a[i+1][j]].max } }
  #=> (1..4).each_with_object(Array.new(4) { [0,0,0,0] }) { |i,b|
  #     (1..4).each { |j|
  #       b[i-1][j-1] = [a[i][j], a[i][j-1], a[i][j+1], a[i-1][j], a[i+1][j]].max } }
  #=> [[0, 1, 0, 0],
  #    [1, 1, 1, 1],
  #    [0, 1, 1, 1],
  #    [0, 0, 0, 1]]
对于不熟悉的读者,最后一句话实际上与下面三行相同

b = Array.new(nbr_rows) { Array.new(nbr_cols) }
(1..nbr_rows).each { |i|
  (1..nbr_cols).each { |j|
    b[i-1][j-1] = [a[i][j], a[i][j-1], a[i][j+1], a[i-1][j], a[i+1][j]].max } }
b

有关Ruby解决方案,请参阅@CarySwoveland的答案

由于您的类名为
Image
,方法名为
blur\u cell
,因此您可能需要检查并删除

您正在寻找的转换称为

使用ImageMagick,您可以轻松完成以下操作:

convert matrix.png -morphology Dilate Diamond dilated_matrix.png
它转化为

要将矩阵转换为位图,或者将矩阵转换为位图,可以使用
这是阅读和编写
.pbm
文件的好方法。

Cary非常感谢您的帮助!我很高兴看到我的错误很小,并且没有什么我不理解的重大问题。谢谢你让我心平气和!另一种选择也很有意义。我仍然在学习不同的方法,尤其是在数组方面。再次感谢你的帮助!我建议您将修复后的代码发布到SO的姐妹站点。在那里你会得到改进它的有用建议。(代码审查需要工作代码。)这难道不适用于位图吗?我想我遗漏了什么。你的解决方案已经很好了,我不想重新发明轮子。如果OP已经在使用位图,他可能根本不需要Ruby。我为矩阵和位图之间的转换添加了一个链接。