0
def peel array
  output = []

  while ! array.empty? do
    output << array.shift
    mutate! array
  end

  output.flatten
end

我没有包括变异!方法,因为我只对删除输出变量感兴趣。变种人!call 很重要,因为我们不能使用 each 遍历数组,因为数组正在改变。

编辑:我得到一个数组作为输出,这就是我想要的。该方法可以正常工作,但我认为有一种方法可以在array.shift不使用临时变量的情况下收集值。

编辑#2:好的,这里是变异!方法和测试用例:

def mutate! array
  array.reverse!
end

a = (1..5).to_a
peel( a ).should == [ 1, 5, 2, 4, 3 ]

peel修改数组没关系。我想应该叫它peel!。是的,mutate!必须在删除每个元素后调用。

4

3 回答 3

1

这一切倒车让我头晕目眩。

def peel(array)
  indices = array.size.times.map do |i|
    i = -i if i.odd?
    i = i/2
  end 
  array.values_at(*indices) # indices will be [0, -1, 1, -2, 2] in the example
end

a = (1..5).to_a
p peel(a) #=>[1, 5, 2, 4, 3]
于 2013-10-06T20:09:38.637 回答
1

另一种方法:

def peel(array)
  mid = array.size/2
  array[0..mid]
    .zip(array[mid..-1].reverse)
    .flatten(1)
    .take(array.size)
end

用法:

peel [1,2,3,4,5,6]
#=> [1, 6, 2, 5, 3, 4]

peel [1,2,3,4,5]
#=> [1, 5, 2, 4, 3]
于 2013-10-06T23:43:34.147 回答
0

这是一种使用并行分配的方法:

def peel array
  n = array.size
  n.times {|i| (n-2-2*i).times {|j| array[n-1-j], array[n-2-j] = array[n-2-j], array[n-1-j]}}
  array      
end

peel [1,2,3,4,5] # => [1,5,2,4,3]
peel [1,2,3,4,5,6] # => [1,6,2,5,3,4]

我在这里做的是一系列成对的交流。例如,对于[1,2,3,4,5,6],前 6-2=4 步(6 是数组的大小)改变数组如下:

[1,2,3,4,6,5]
[1,2,3,6,4,5]
[1,2,6,3,4,5]
[1,6,2,3,4,5]

1、6 和 2 现在处于正确的位置。我们重复这些步骤,但这次仅 6-4=2 次,将 5 和 3 移动到正确的位置:

[1,6,2,3,5,4]
[1,6,2,5,3,4]

4被推到最后,这是正确的位置,所以我们完成了。

于 2013-10-06T23:00:09.820 回答