Встановити операції (об'єднання, перехрестя) на масиві Swift?


100

Чи є якісь стандартні виклики бібліотеки, які я можу використовувати, щоб виконувати задані операції на двох масивах, або самостійно реалізовувати таку логіку (в ідеалі максимально функціонально та ефективно)?


Набір може бути реалізований поверх словника, якщо ви хочете зробити це самостійно.
CodaFi

@CodaFi Ви маєте на увазі, використовуючи клавіші, щоб забезпечити унікальність?
devios1

Чи можете ви просто використовувати `Словник <Рядок, недійсність>?
Девід Беррі

Відповіді:


184

Так, у Свіфта є Setклас.

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+ може робити операції на наборах як:

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

Swift 2.0 може обчислювати аргументи масиву:

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

Swift 1.2+ може обчислювати набори:

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

Якщо ви використовуєте власні структури, вам потрібно реалізувати Hashable.

Дякуємо Майклу Стерну в коментарях до оновлення Swift 2.0.

Дякую Амджаду Хуссейні за коментарі до інформації про Hashable.


8
Зауважте, що, як мінімум, від Swift 2.0, ви можете передавати масив як аргумент цим функціям. Таким чином, set1.union(array2)і set1.exclusiveOr(array2)обидва є законними, крім форм, показаних вище.
Майкл Стерн

Що робити, якщо ви хочете перетинати 5 масивів? Або 6? Що робити, якщо кількість масивів невідома?
Натан Маккаскле

2
@Nathan Залежить від заданої операції. Наприклад, встановлення об'єднання та перетину множин є комутативно-асоціативними, тому ви можете обробити безліч наборів, використовуючи ітерацію чи ланцюжок. Або ви можете створити власні методи, які використовують вар-арги, такі як Встановити union_all (...) та intersect_all (...).
joelparkerhenderson

Що робити, якщо ваші масиви містять повторювані значення, наприклад, щоб визначити, чи 0 $ є анаграмою в $ 1, де символи введення можуть мати повторювані літери?
Дейв Климан

1
Якщо ви використовуєте власні структури, вам доведеться відповідати Hashable, що може бути прикро, якщо у вас складна структура
Amjad Husseini

0

Немає жодних стандартних дзвінків з бібліотеки, але ви можете поглянути на бібліотеку ExSwift . Він включає в себе купу нових функцій на масивах, включаючи різницю, перетин та об'єднання.


1
Попереджувальна примітка: я використовував ExSwift без проблем для Swift 1.x, але він здається досить зламаним для Swift 2.x, і станом на цей час оновлення не оновлювалося протягом декількох місяців. Є тонна виделок, які можуть привернути більше уваги.
Робін Мачарг


0

Найбільш ефективний метод, який я знаю, - це використання чисел Godel. Google для кодування Godel

Ідея така. Припустимо, у вас є N можливих чисел і потрібно скласти їх набори. Наприклад, N = 100 000 і хочуть зробити набори типу {1,2,3}, {5, 88, 19000} і т.д.

Ідея полягає у збереженні списку N простих чисел у пам'яті, а для заданого набору {a, b, c, ...} ви кодуєте його як

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

Таким чином, ви кодуєте набір як BigNumber. Операції з BigNumbers, незважаючи на те, що вони повільніші, ніж операції з Integers, все ще дуже швидкі.

Щоб об'єднати 2 множини A, B, ви берете

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

найменший-загальний-кратний A і B, як A і B - це множини і обидва числа.

Щоб зробити перехрестя, яке ви берете

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

найбільший спільний дільник.

і так далі.

Це кодування називається godelization, ви можете шукати в Google ще більше, вся мова арифметики, написана за допомогою логіки Frege, може бути закодована, використовуючи числа таким чином.

Щоб отримати операцію-члена? це дуже просто -

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

Отримати кардинала трохи складніше -

CARDINAL(S) = # of prime factors in s

ви розкладаєте число S, що представляє множину у добутку простих факторів, і додаєте їхні показники. Якщо набір не дозволяє дублікати, у вас будуть всі показники 1.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.