在Ruby中使用while循环交换两个数字

时间:2014-04-20 05:45:47

标签: ruby

我想在Ruby中从[[2, 1, 3], [1, 3, 2]]获取[1, 2, 3]

对于[1, 2, 3, 4],我想[[2,1,3,4],[1,3,2,4],[1,2,4,3]] < / p>

规则:在两个数字内,如果留下一个较小,则交换位置。

到目前为止,我有以下代码,但它返回[[2, 3, 1], [2, 3, 1]]

我在这里做错了什么?我很感激任何投入。

在amidakuji.rb

class Amidakuji
  def initialize(column, rung)
    @column = column
    @rung = rung
    @myarr = []
    @per_arr = []
    @build_arr = []
  end

  def build_initial
    @arr = (1..@column).to_a
  end

  def swap_element 
    i = 0
    arr = build_initial
    while i < @column - 1 do
      @build_arr << swap(arr, i)
      i += 1
    end
    @build_arr
  end

  def swap(arr, a)
    if arr[a] < arr[a + 1]
      arr[a], arr[a + 1] = arr[a + 1], arr[a]
    end
    arr
  end
end

在amidakuji_spec.rb

    it 'should create an array with swapped elements' do
      expect(@kuji1.swap_element).to eq ([[2, 1, 3], [1, 3, 2]])
    end

结果

Failures:
   expected: [[2, 1, 3], [1, 3, 2]]
        got: [[2, 3, 1], [2, 3, 1]]

2 个答案:

答案 0 :(得分:1)

使用方法Enumerable#each_consEnumerable#map可以非常紧凑地完成此操作。

<强>代码

def doit(arr)
  (0...arr.size).each_cons(2).map do |i,j|
    a = arr.dup
    a[i], a[j] = a[j], a[i]
    a
  end    
end

<强>实施例

doit([1,2,3])     #=> [[2, 1, 3], [1, 3, 2]]
doit([1,2,3,4])   #=> [[2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3]]
doit([1,2,3,4,5]) #=> [[2, 1, 3, 4, 5], [1, 3, 2, 4, 5],
                  #=>  [1, 2, 4, 3, 5], [1, 2, 3, 5, 4]]

<强>解释

arr = [1,2,3,4]

b = (0...arr.size).each_cons(2)
  #=> #<Enumerator: 0...4:each_cons(2)>

要查看此枚举器的内容:

b.to_a
  #=> [[0, 1], [1, 2], [2, 3]]

最后

b.map do |i,j|
  a = arr.dup
  a[i], a[j] = a[j], a[i]
  a
end
  #=> [[2, 1, 3, 4], [1, 3, 2, 4], [1, 2, 4, 3]]

在最后一步中,考虑传递给b的{​​{1}}的第一个元素,它将以下值分配给块变量:

map

然后我们制作i => 0 j => 1 的副本,交换元素偏移arr0,制作

1

然后在阻止的末尾输入a => [2, 1, 3, 4] ,导致a用该数组替换map

答案 1 :(得分:0)

考虑到您尝试完成的内容以及您获得的输出,当您需要使用不同的数组时,您似乎正在重复使用相同的数组。特别是这一行:

@build_arr << swap(arr, i)

总是传递相同的&#39; arr&#39;交换。

所以第一次,它交换1和2给你[2,1,3] 第二次,它交换1和3给你[2,3,1]

你将同一个数组推到@build_arr两次,这就是重复的原因。