Вопрос по ruby – Проверьте, является ли массив подмножеством другого массива в Ruby

21

Как я могу проверить, является ли один массив подмножеством другого массива, независимо от порядка элементов?

<code>a1 = [3, 6, 4]
a2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

...?

a1 is a subset of a2
</code>
Может быть. Массивы и Хэши - это правильные структуры данных? That Umbrella Guy
Ой,которы состав. Лучше всего это наборы, так как именно в этом наборы хороши - но, как показывает разнообразие ответов (и вариантов еще больше), это может не иметь значения - в зависимости от ваших потребностей. Dave Newton
Ты действительно имеешь в виду структуру данных? Flexoid
В настоящее время я не ожидаю дубликатов, но я полагаю, что в конечном итоге я буду работать с наборами, которые содержат повторяющиеся значения, где я на самом деле хочу сказать: «дубли не имеют значения». Это вызвало бы проблему с массивами? That Umbrella Guy
Могут ли быть дубликаты в a1 или a2? Если в a1 могут быть дубликаты, должно ли быть такое же количество или больше дубликатов в a2? Другими словами, каким должен быть результат, если ваши переменные имеют значенияa1 = [1, 1] а такжеa2 = [1,2,3,4,5,6,7,8,9]? Mark Byers

Ваш Ответ

4   ответа
1

Возможно, не быстро, но вполне читабельно

def subset?(a,b)
  a.all? {|x| b.include? x}
end
35

Самый простой может быть:

(a1 - a2).empty?
Это правильный ответ, поскольку он предотвращает инициализацию новых объектов и засорение памяти. Здесь создается только пересечение. user2076066
set - это stdlib, поэтому можно утверждать, что он менее чист, чем использование различий в списке. rewritten
Это чистый рубин и не нуженrequire "set" Pankaj Tyagi
31

Используйте наборы. Тогда вы можете использоватьset.subset?. Пример

require 'set'

a1 = Set[3,6,4]
a2 = Set[1,2,3,4,5,6,7,8,9]

puts a1.subset?(a2)

Выход

true

Смотри, как работает онлайн: Ideone

Еще одним преимуществом Set является то, что вы также можете проверить другие свойства, такие какproper_subset? если вы не хотите, чтобы идентичные множества возвращали истину. Mark Thomas
23

просто проверьте пересечение:

(a1 & a2) == a1

Обновить Комментарий, обсуждающий перестановки, интересен и креативен, но совершенно некорректен, так как разработчики Ruby предвидели эту проблему и указали, что порядок результата равен порядкуa1. Так что это работает, и будет продолжать работать в будущем. (Массивы - это упорядоченные структуры данных, а не наборы. Вы не можете просто изменить порядок операций с массивами.)

Мне очень нравится Дэйв Ньютонтвет @ для крутости, но этот ответ также работает, и, как и Дейв, также является ядром Ruby.

Просто возьми перекресток и проверь. Не думал об этом LOL That Umbrella Guy
+ 1, тоже лучше, чем у меня. Dave Newton
Я не уверен, что мой действительно лучше, так как это зависит от того, является ли реализация устойчивой к сортировке. (Также нет дубликатов, но определение вопроса как операции над множеством, по-видимому, подразумевает это. Полагаю, можно отсортировать оба термина.) DigitalRoss
@ istrasci, основные документы указываются в Ruby-doc.org / ядро-2.3.1 / Array.html # метод-я-26 что Порядок сохраняется из исходного массива. Это работает правильно и продолжит это делать в будущем, так как это поведение является частью спецификации& метод наArray. Поэтому сортировать результат также не обязательно. DigitalRoss
Я понимаю, что этому ответу почти 4 года, но это не обязательно работает.a1 & a2 даст Перестановка of a1, который, если элементы не в том же порядке, даст false при сравнении== до a1. Например,a1=%w(a c); a2= %w(a b c); perm=a1&a2; (may give ['c','a']); perm==a1 => false. То, что гарантированно работает, этоa1.permutation.include?(a1&a2). istrasci

Похожие вопросы