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].



@ 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]

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


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.