Wie kann ich den Schnittpunkt, die Vereinigung und die Teilmenge von Arrays in Ruby ermitteln?

170

Ich möchte verschiedene Methoden für eine Klasse namens Multiset erstellen .

Ich habe alle erforderlichen Methoden, bin mir aber nicht sicher, wie ich Schnitt-, Vereinigungs- und Teilmengenmethoden schreiben soll.

Für Schnittmenge und Vereinigung beginnt mein Code wie folgt:

def intersect(var)
  x = Multiset.new
end

Hier ist ein Beispiel:

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

dann wird der Schnittpunkt von Xund Yist [1, 2].

user487743
quelle
@ Krules Link ist defekt, aber ich glaube, er hat Sie auf die Array "&" -Methode hingewiesen, die Schnittpunkte ausführt. Einige der Antworten finden Sie hier.
Rogerdpack
Das wurde vor mehr als 8 Jahren beantwortet. Ja, das war Kreuzung, ruby-doc.org/core-2.6.3/Array.html#method-i-26
Krule

Antworten:

151

Nutzen Sie die Tatsache, dass Sie Set-Operationen für Arrays ausführen können, indem Sie &(Schnittmenge), -(Differenz) und |(Vereinigung) ausführen .

Natürlich habe ich das MultiSet nicht gemäß Spezifikation implementiert, aber dies sollte Ihnen den Einstieg erleichtern:

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]
Mike Lewis
quelle
8
2 große Verbrechen in dieser Antwort: (1) Das Wort setals Variablenname eines einfachen Arrays; (2) Replizieren von allem, was Arraybereits funktioniert. Wenn das OP der ArrayKlasse mit einigen zusätzlichen Methoden Funktionen hinzufügen möchte , sollten Sie einfach class MultiSet < Array def inclusion?(other) Set.new(self).subset?(Set.new(other)) end end
Folgendes
1
Einverstanden ... dies ist wahrscheinlich die nutzloseste Klasse, die ich in meinem Leben gesehen habe ... aber mir ist klar, dass das nicht wirklich deine Schuld ist.
mpowered
313

Ich nehme an Xund Ysind Arrays? Wenn ja, gibt es einen sehr einfachen Weg, dies zu tun:

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]

Quelle

Jon Gauthier
quelle
17
Mit anderen Worten, tun Sie es einfach Multiset < Array.
Sawa
Was ist, wenn Sie x = [1,1,2,4] y = [1,2,2,2] z = [4] haben? setzt? Also anstatt dir [] zu geben, gibt es dir [1,2,4]?
mharris7190
1
@ mharris7190 Sie können die Vereinigung all dieser Kreuzungen nehmen:(x & y) | (y & z) | (x & z)
xavdid
2
Vergessen Sie nicht, dass es auch &=gibt |=, und -=wenn Sie auch sofort den Wert speichern möchten, wie ich es getan habe! :)
Pysis
2
Genau das, was ich dachte @sawa. Warum erstellt das OP diese Klasse überhaupt? Es macht nichts, was Array noch nicht aus Rubys Standard Lib macht.
Danielricecodes
6

Wenn Multiseterstreckt sich von der ArrayKlasse

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

UNION

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]

UNTERSCHIED

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

ÜBERSCHNEIDUNG

x & y                # => [1, 2]

Weitere Informationen zu den neuen Methoden in Ruby 2.6 finden Sie in diesem Blogbeitrag zu den neuen Funktionen

Ana María Martínez Gómez
quelle