¿Cómo puedo obtener la intersección, unión y subconjunto de matrices en Ruby?


170

Quiero crear diferentes métodos para una clase llamada Multiset .

Tengo todos los métodos requeridos, pero no estoy seguro de cómo escribir los métodos de intersección, unión y subconjunto.

Para intersección y unión, mi código comienza así:

def intersect(var)
  x = Multiset.new
end

Aquí hay un ejemplo:

X = [1, 1, 2, 4]
Y = [1, 2, 2, 2]

entonces la intersección de Xy Yes [1, 2].



El enlace de @ Krule está roto, pero creo que te estaba señalando el método "&" de Array que hace intersección, mira algunas de las respuestas aquí.
rogerdpack

Eso fue respondido hace más de 8 años. Sí, eso fue intersección, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Krule

Respuestas:


151

Aprovechando el hecho de que puede establecer operaciones en matrices haciendo &(intersección), -(diferencia) y |(unión).

Obviamente no implementé el MultiSet para especificar, pero esto debería ayudarlo a comenzar:

class MultiSet
  attr_accessor :set
  def initialize(set)
    @set = set
  end
  # intersection
  def &(other)
    @set & other.set
  end
  # difference
  def -(other)
    @set - other.set
  end
  # union
  def |(other)
    @set | other.set
  end
end

x = MultiSet.new([1,1,2,2,3,4,5,6])
y = MultiSet.new([1,3,5,6])

p x - y # [2,2,4]
p x & y # [1,3,5,6]
p x | y # [1,2,3,4,5,6]

8
2 grandes crímenes en esta respuesta: (1) La palabra setcomo nombre variable de una matriz simple; (2) Replicando todo lo que Arrayya hace. Si el OP quiere agregar funcionalidad a la Arrayclase con algunos métodos adicionales, simplemente debe hacer: class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Rahul Murmuria

1
De acuerdo ... esta es probablemente la clase más inútil que he visto en mi vida ... pero me doy cuenta de que no es realmente tu culpa.
Desarrollado el

313

Supongo Xy Yson matrices? Si es así, hay una manera muy simple de hacer esto:

x = [1, 1, 2, 4]
y = [1, 2, 2, 2]

# intersection
x & y            # => [1, 2]

# union
x | y            # => [1, 2, 4]

# difference
x - y            # => [4]

Fuente


17
En otras palabras, solo hazlo Multiset < Array.
sawa

¿Qué pasa si tienes x = [1,1,2,4] y = [1,2,2,2] z = [4] ¿Cómo puedes conseguir que te dé intersecciones entre conjuntos en lugar de la intersección de todos conjuntos? Entonces, en lugar de darte [], ¿te da [1,2,4]?
mharris7190

1
@ mharris7190 se puede tomar la unión de todas esas intersecciones:(x & y) | (y & z) | (x & z)
xavdid

2
No se olvide también existe &=, |=y -=si también desea almacenar el valor de inmediato como lo hice! :)
Pysis

2
Exactamente lo que pensaba @sawa. ¿Por qué el OP está creando esta clase en primer lugar? No hace nada que Array no haga desde Ruby's Standard Lib.
danielricecodes

6

Si se Multisetextiende desde la Arrayclase

x = [1, 1, 2, 4, 7]
y = [1, 2, 2, 2]
z = [1, 1, 3, 7]

UNIÓN

x.union(y)           # => [1, 2, 4, 7]      (ONLY IN RUBY 2.6)
x.union(y, z)        # => [1, 2, 4, 7, 3]   (ONLY IN RUBY 2.6)
x | y                # => [1, 2, 4, 7]

DIFERENCIA

x.difference(y)      # => [4, 7] (ONLY IN RUBY 2.6)
x.difference(y, z)   # => [4] (ONLY IN RUBY 2.6)
x - y                # => [4, 7]

INTERSECCIÓN

x & y                # => [1, 2]

Para obtener más información sobre los nuevos métodos en Ruby 2.6, puede consultar esta publicación de blog sobre sus nuevas características

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.