Operationen (Vereinigung, Schnittmenge) für das Swift-Array festlegen?

99

Gibt es Standardbibliotheksaufrufe, mit denen ich entweder Set-Operationen für zwei Arrays ausführen oder diese Logik selbst implementieren kann (idealerweise so funktional und auch effizient wie möglich)?

devios1
quelle
Ein Satz kann über einem Wörterbuch implementiert werden, wenn Sie dies selbst tun möchten.
CodaFi
@CodaFi Meinst du mit den Schlüsseln, um die Eindeutigkeit zu gewährleisten?
Devios1
Könnten Sie einfach `Dictionary <String, Void> verwenden?
David Berry

Antworten:

183

Ja, Swift hat die SetKlasse.

let array1 = ["a", "b", "c"]
let array2 = ["a", "b", "d"]

let set1:Set<String> = Set(array1)
let set2:Set<String> = Set(array2)

Swift 3.0+ kann Operationen an Sets ausführen als:

firstSet.union(secondSet)// Union of two sets
firstSet.intersection(secondSet)// Intersection of two sets
firstSet.symmetricDifference(secondSet)// exclusiveOr

Swift 2.0 kann mit Array-Argumenten rechnen:

set1.union(array2)       // {"a", "b", "c", "d"} 
set1.intersect(array2)   // {"a", "b"}
set1.subtract(array2)    // {"c"}
set1.exclusiveOr(array2) // {"c", "d"}

Swift 1.2+ kann auf Sätzen rechnen:

set1.union(set2)        // {"a", "b", "c", "d"}
set1.intersect(set2)    // {"a", "b"}
set1.subtract(set2)     // {"c"}
set1.exclusiveOr(set2)  // {"c", "d"}

Wenn Sie benutzerdefinierte Strukturen verwenden, müssen Sie Hashable implementieren.

Vielen Dank an Michael Stern in den Kommentaren zum Swift 2.0 Update.

Vielen Dank an Amjad Husseini in den Kommentaren für die Hashable-Info.

joelparkerhenderson
quelle
8
Beachten Sie, dass Sie mindestens ab Swift 2.0 ein Array als Argument an diese Funktionen übergeben können. So set1.union(array2)und set1.exclusiveOr(array2)sind sowohl legitim, zusätzlich zu den Formen gezeigt oben.
Michael Stern
Was ist, wenn Sie 5 Arrays schneiden möchten? Oder 6? Was ist, wenn die Anzahl der Arrays unbekannt ist?
Nathan McKaskle
2
@ Nathan Hängt von der eingestellten Operation ab. Zum Beispiel sind Mengenvereinigung und Mengenschnittpunkt kommutativ und assoziativ, sodass Sie viele Mengen mithilfe von Iteration oder Verkettung verarbeiten können. Sie können auch benutzerdefinierte Methoden erstellen, die var args verwenden, z. B. Set union_all (...) und intersect_all (...).
Joelparkerhenderson
Was ist, wenn Ihre Arrays doppelte Werte enthalten, um beispielsweise festzustellen, ob $ 0 ein Anagramm von $ 1 ist, bei dem die Eingabezeichen doppelte Buchstaben haben könnten?
Dave Kliman
1
Wenn Sie benutzerdefinierte Strukturen verwenden, müssen Sie Hashable anpassen, was ärgerlich sein kann, wenn Sie eine komplizierte Struktur haben
Amjad Husseini
0

Es gibt keine Standardbibliotheksaufrufe, aber Sie können sich die ExSwift- Bibliothek ansehen . Es enthält eine Reihe neuer Funktionen für Arrays, einschließlich Differenz, Schnittmenge und Vereinigung.

Connor
quelle
1
Ein Warnhinweis: Ich habe ExSwift ohne Probleme für Swift 1.x verwendet, aber es scheint für Swift 2.x ziemlich kaputt zu sein, und zum jetzigen Zeitpunkt wurde dieses Schreiben seit einigen Monaten nicht mehr aktualisiert. Es gibt eine Menge Gabeln, die möglicherweise mehr Aufmerksamkeit erhalten.
Robin Macharg
0

Die effizienteste Methode, die ich kenne, ist die Verwendung von Gödelnummern. Google für Godel-Codierung.

Die Idee ist so. Angenommen, Sie haben N mögliche Zahlen und müssen Sätze daraus erstellen. Zum Beispiel ist N = 100.000 und möchte Mengen wie {1,2,3}, {5, 88, 19000} usw. erstellen.

Die Idee ist, die Liste der N Primzahlen im Speicher zu behalten und für eine gegebene Menge {a, b, c, ...} als zu codieren

 prime[a]*prime[b]*prime[c]*...

Sie codieren also einen Satz als BigNumber. Die Operationen mit BigNumbers sind immer noch sehr schnell, obwohl sie langsamer sind als Operationen mit Ganzzahlen.

Um 2 Sätze A, B zu vereinen, nehmen Sie

  UNITE(A, B) = lcm(a, b)

Das niedrigste gemeinsame Vielfache von A und B als A und B sind Mengen und beide Zahlen.

Um die Kreuzung zu machen, nehmen Sie

 INTERSECT(A, B) = gcd (a, b)

größter gemeinsamer Teiler.

und so weiter.

Diese Codierung wird als Godelisierung bezeichnet. Sie können nach mehr googeln. Die gesamte Sprache der Arithmetik, die mit der Logik von Frege geschrieben wurde, kann auf diese Weise mit Zahlen codiert werden.

Um die Operation zu bekommen, ist-Mitglied? es ist sehr einfach --

ISMEMBER(x, S) = remainder(s,x)==0

Um den Kardinal zu bekommen, ist es etwas komplizierter -

CARDINAL(S) = # of prime factors in s

Sie zerlegen die Zahl S, die die Menge der Primfaktoren darstellt, und addieren deren Exponenten. Falls die Menge keine Duplikate zulässt, haben Sie alle Exponenten 1.

Alinsoar
quelle