Рубиновые комбинации с элементами массива - PullRequest
1 голос
/ 05 января 2012

Хорошо, я искал ответы в Интернете, а также часами искал в своем программисте ruby, но я не могу разобраться с этим. Я пишу скрипт для создания всевозможных комбинаций из элементов в массиве.

ar = ["a","b","c","d"]

На данный момент я могу сделать следующие комбинации:

["a"],["a","b"],["a","b","c"],["a","b","c","d"],["b"],["b","c"],["b","c","d"],["c"],["c","d"],["d"]

Это нормально, но я не могу найти способ поиска этих комбинаций, например ["a","c"] or ["a","c","d"] or ["a","d"] и т. Д. *

Пока мой код выглядит так:

def combinaties(array)
  combinaties = []
  i=0
  while i <= array.length-1
    combinaties << array[i]
    unless i == array.length-1
      array[(i+1)..(array.length-1)].each{|volgend_element|
        combinaties<<(combinaties.last.dup<<volgend_element)
      }
    end
    i+=1
  end
end

Ответы [ 3 ]

9 голосов
/ 05 января 2012

Функциональный подход (требуется Ruby> = 1.9) для создания powerset массива (за исключением пустого элемента, который вам, кажется, не нужен):

xs = ["a", "b", "c", "d"]
yss = 1.upto(xs.size).flat_map do |n|
  xs.combination(n).to_a
end

#[
#  ["a"], ["b"], ["c"], ["d"],
#  ["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"],
#  ["a", "b", "c"], ["a", "b", "d"], ["a", "c", "d"], ["b", "c", "d"],
#  ["a", "b", "c", "d"],
#]
4 голосов
/ 05 января 2012

Существует тривиальное соответствие (биекция) между такими комбинациями и числами в [1 .. (2 ^ m - 1)] (m - длина массива).

Рассмотрим такое число n. Это двоичное представление имеет m цифр (включая ведущие нули). Позиции цифр, равных 1, являются индексами элементов в соответствующей комбинации.

Код будет:

def combinations(array)
  m = array.length
  (1...2**m).map do | n |
    (0...m).select { | i | n[i] == 1 }.map { | i | array[i] }
  end
end
2 голосов
/ 05 января 2012

Или в рубине 1.9

%w(a b c d e).combination(3).to_a

даст вам все комбинации размера 3.

...