从Ruby中的数组中选择两个元素

时间:2016-05-14 03:12:22

标签: arrays ruby loops

假设有一个像这样的数组:

list = ["a", "a", "a", "b", "b", "c", "d", "e", "e"]

我们想要创建一个循环,其中每个下一个元素都与前一个元素不同,并且第一个元素与最后一个元素不同。

required = ["a", "b", "a", "b", "a", "c", "e", "d", "e"]

如何在红宝石中完成?

def create_cycle
  temp = Array.new($input)
  i, j, counter = 0
  while i == 0
    while (counter != $input.length)
      j = rand(1..$input.length-1).floor
      unless !($input[i][0].to_s.eql?$input[j][0])
        $solution.push($input[i])
        $solution.push($input[j])
        puts input[i], input[j]
        $input.delete_at(i)
        $input.delete_at(j)
        counter = counter + 1
      end
    end
  end
end

我正在努力学习这一点。谢谢您的帮助。

附加说明:

  1. 元素a,b,c,d,e表示特殊格式字符串,其中
    某些属性在它们中很常见,因此第一个元素“a” 与下一个元素“a”共享一个属性,但不等同于 首先。
  2. 如果无法创建循环,那么在命令行中引发标志就足够了。

3 个答案:

答案 0 :(得分:1)

我可能会这样做:

>> list = [a, a, a, b, b, c, d, e, e]
>> list.sort.each_slice((list.size/2.0).round).reduce(:zip).flatten.compact
=> [a, c, a, d, a, e, b, e, b]

一般方法是:

  1. 对列表进行排序,因此所有相同的成员都相邻
  2. 将列表从中间分成两半
  3. 将两半交织在一起

答案 1 :(得分:1)

假设您不关心顺序与原始数组中的相同,并且如果没有办法可以重复,并且假设列表是预先排序的,这里有一种方法 - 它只是不断添加从列表的开头和结尾开始的元素,直到没有元素为止:

def interleaver list
  result = []
  el = list.first
  while(el)
    el = list.shift
    if el
      result << el
    else
      return result
    end
    el = list.pop
    if el
      result << el
    else
      return result
    end
  end 
  result
end

> a = 'a'
> b = 'b'
> c = 'c'
> d = 'd'
> e = 'e'
> list = [a, a, a, b, b, c, d, e, e]
> interleaver(list)
=> ["a", "e", "a", "e", "a", "d", "b", "c", "b"]

但如果无法进行此类交错,您将获得重复:

> list = [a, a, a, b]
> interleaver(list)
#=> ["a","b","a","a"]

答案 2 :(得分:1)

您可以使用以下递归方法获取此类字符串,或演示不存在此类字符串。

<强>代码

def doit(remaining, partial=[])
  first_partial, last_partial = partial.first, partial.last
  if remaining.size == 1
    return ([first_partial, last_partial] & remaining).empty? ?
      partial + remaining : nil
  end
  remaining.uniq.each_with_index do |s,i|
    next if s == last_partial
    rem = remaining.dup
    rem.delete_at(i)
    rv = doit(rem, partial + [s])
    return rv if rv
  end
  nil
end

<强>实施例

list = %w| a a b |
  #=> ["a", "a", "b"]
doit list
  #=> nil

以上表明list的三个元素不能被置换以满足两个排序要求。

list = %w| a a a b b c d e e |
  #=> ["a", "a", "a", "b", "b", "c", "d", "e", "e"] 
doit list    
  #=> ["a", "b", "a", "b", "c", "b", "e", "d", "e"] 

这需要0.0042秒来解决新的MacBook Pro。

list = %w| a a a a a a a b b c d e e f f f g g g g h i i i i j j |
  #=> ["a", "a", "a", "a", "a", "a", "a", "b", "b", "c", "d", "e", "e",
  #    "f", "f", "f", "g", "g", "g", "g", "h", "i", "i", "i", "i", "j", "j"] 
doit list    
  #=> ["a", "b", "a", "b", "a", "b", "a", "b", "c", "b", "d", "e", "f",
  #    "e", "f", "g", "f", "g", "h", "g", "h", "i", "j", "i", "j", "i", "j"] 

这需要0.0059秒来解决。

出于好奇,我接着尝试了

list = (%w| a a a a a a a b b c d e e f f f g g g g h i i i i j j |).shuffle
  #=> ["a", "c", "f", "b", "d", "i", "a", "a", "i", "a", "a", "g", "g",
  #    "a", "g", "i", "j", "b", "h", "j", "e", "e", "a", "g", "f", "i", "f"] 
doit list    
  #=> ["a", "c", "f", "b", "d", "i", "a", "i", "a", "g", "a", "g", "a",
  #    "g", "i", "g", "j", "b", "h", "j", "e", "a", "e", "g", "f", "i", "f"] 

这需要花费1.16秒来解决,这表明如果list可以排序,可能需要预先排序doit(list.sort)list)。