在 Swift 数组上设置操作(联合、交集)?
Posted
技术标签:
【中文标题】在 Swift 数组上设置操作(联合、交集)?【英文标题】:Set operations (union, intersection) on Swift array? 【发布时间】:2014-08-26 16:07:11 【问题描述】:是否有任何标准库调用可以用来对两个数组执行集合操作,或者自己实现这样的逻辑(理想情况下,功能和效率都尽可能)?
【问题讨论】:
如果你想自己做一个集合,可以在字典之上实现。 @CodaFi 你的意思是用keys来保证唯一性吗? 你能用`Dictionary没有任何标准库调用,但您可能想查看ExSwift 库。它包含了一系列关于数组的新函数,包括差分、交集和并集。
【讨论】:
警告:我在 Swift 1.x 上一直使用 ExSwift 没有问题,但在 Swift 2.x 上似乎很糟糕,并且在撰写本文时几个月内还没有更新.有很多分叉可能会受到更多关注。【参考方案2】:您可能希望遵循与 Objective-C 相同的模式,后者也缺少此类操作,但有一个简单的解决方法:
how to intersect two arrays in objective C?
【讨论】:
【参考方案3】:是的,Swift 有 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。
感谢 cmets 中的 Michael Stern 提供 Swift 2.0 更新。
感谢 cmets 中的 Amjad Husseini 提供 Hashable 信息。
【讨论】:
请注意,至少从 Swift 2.0 开始,您可以将数组作为参数传递给这些函数。因此,set1.union(array2)
和 set1.exclusiveOr(array2)
都是合法的,除了上面显示的形式。
如果要相交5个数组怎么办?还是6?如果数组数量未知怎么办?
@Nathan 取决于设置操作。例如,集合并集和集合交集是可交换的和关联的,因此您可以使用迭代或链接来处理多个集合。或者您可以创建使用 var args 的自定义方法,例如 Set union_all(...) 和 intersect_all(...)。
如果您的数组包含重复值怎么办,例如确定 $0 是否是 $1 的字谜,其中输入字符可能有重复的字母?
如果你使用自定义结构,你必须符合 Hashable,如果你有一个复杂的结构,这可能会很烦人【参考方案4】:
我所知道的最有效的方法是使用 godel 数。 Google for 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一下,所有用弗雷格逻辑写的算术语言都可以用数字编码。
要获取操作is-member?很简单——
ISMEMBER(x, S) = remainder(s,x)==0
要获得红衣主教有点复杂--
CARDINAL(S) = # of prime factors in s
你分解代表素数乘积中集合的数字 S 并添加它们的指数。如果集合不允许重复,您将拥有所有指数 1。
【讨论】:
以上是关于在 Swift 数组上设置操作(联合、交集)?的主要内容,如果未能解决你的问题,请参考以下文章