Swift dizisindeki operasyonları (birleşim, kesişim) ayarla?


100

Ya iki dizi üzerinde set işlemleri gerçekleştirmek ya da bu mantığı kendim uygulamak için kullanabileceğim standart kitaplık çağrıları var mı (ideal olarak işlevsel ve aynı zamanda mümkün olduğunca verimli)?


Kendiniz yapmak istiyorsanız, bir sözlüğün üstüne bir küme uygulanabilir.
CodaFi

@CodaFi Benzersizliği sağlamak için anahtarları kullanmayı mı kastediyorsunuz?
devios1

Sadece `Dictionary <String, Void> kullanabilir misin?
David Berry

Yanıtlar:


185

Evet, Setsınıfta Swift var .

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+ setler üzerinde şu işlemleri yapabilir:

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

Swift 2.0, dizi argümanlarını hesaplayabilir:

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

Swift 1.2+ setlerde hesaplama yapabilir:

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

Özel yapılar kullanıyorsanız, Hashable'ı uygulamanız gerekir.

Swift 2.0 güncellemesinin yorumlarında Michael Stern'e teşekkürler.

Hashable bilgi için yorumlarda Amjad Husseini'ye teşekkürler.


8
En azından Swift 2.0'dan itibaren, bu işlevlere argüman olarak bir dizi geçirebileceğinizi unutmayın. Bu nedenle, set1.union(array2)ve set1.exclusiveOr(array2)yukarıda gösterilen biçimlerine ek olarak, her ikisi de meşru.
Michael Stern

Ya 5 diziyi kesişmek istersen? Veya 6? Ya dizi sayısı bilinmiyorsa?
Nathan McKaskle

2
@Nathan Ayarlanan işleme bağlıdır. Örneğin, set birleşimi ve küme kesişimi değişmeli ve ilişkilidir, böylece yineleme veya zincirleme kullanarak birçok kümeyi işleyebilirsiniz. Veya Set union_all (...) ve intersect_all (...) gibi değişken args kullanan özel yöntemler oluşturabilirsiniz.
joelparkerhenderson

Peki ya dizileriniz yinelenen değerler içeriyorsa, örneğin $ 0'ın giriş karakterlerinin yinelenen harflere sahip olabileceği 1 $ 'lık bir anagram olup olmadığını belirlemek için?
Dave Kliman

1
Özel yapılar kullanıyorsanız, Hashable'a uymanız gerekir, bu karmaşık bir yapınız varsa can sıkıcı olabilir
Amjad Husseini

0

Herhangi bir standart kitaplık çağrısı yoktur, ancak ExSwift kitaplığına bakmak isteyebilirsiniz . Arrays üzerinde fark, kesişim ve birleşim gibi bir dizi yeni işlev içerir.


1
Bir uyarı notu: ExSwift'i Swift 1.x için sorunsuz kullanıyordum, ancak Swift 2.x için oldukça bozuk görünüyor ve bu yazı itibariyle birkaç aydır güncellenmedi. Daha fazla dikkat çekebilecek bir ton çatal var.
Robin Macharg


0

Bildiğim en verimli yöntem, godel sayıları kullanmaktır. Godel kodlama için Google.

Fikir böyledir. Varsayalım, N olası sayınız var ve bunlardan setler yapmanız gerekiyor. Örneğin, N = 100.000 ve {1,2,3}, {5, 88, 19000} vb. Gibi kümeler yapmak istiyor.

Buradaki fikir, N asal sayı listesini bellekte tutmak ve belirli bir küme için {a, b, c, ...} olarak kodlamaktır.

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

Yani bir seti BigNumber olarak kodlarsınız. BigNumbers ile yapılan işlemler, Tamsayılarla yapılan işlemlerden daha yavaş olmalarına rağmen hala çok hızlı.

2 set A, B'yi birleştirmek için

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

A ve B olarak A ve B'nin en düşük-ortak-katı kümeler ve her iki sayıdır.

Aldığın kavşağı yapmak için

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

en büyük ortak böleni.

ve bunun gibi.

Bu kodlamaya gode bırakma denir, daha fazlası için google'da yapabilirsiniz, Frege mantığıyla yazılan tüm aritmetik dilleri bu şekilde sayılar kullanılarak kodlanabilir.

Operasyonu almak için üye olur mu? o çok basit --

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

Kardinali almak için biraz daha karmaşık -

CARDINAL(S) = # of prime factors in s

Asal çarpanlar çarpımındaki kümeyi temsil eden S sayısını ayrıştırır ve üslerini eklersiniz. Kümenin kopyalara izin vermemesi durumunda, tüm üslere sahip olacaksınız 1.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.