# 《swift-algorithm-club》——数据结构/集合

·  阅读 974

### 集合(Sets)

#### 布隆过滤器

``````public init(size: Int = 1024, hashFunctions: [(T) -> Int]) {
self.array = [Bool](repeating: false, count: size)
self.hashFunctions = hashFunctions
}

``````public func insert(_ element: T) {
for hashValue in computeHashes(element) {
array[hashValue] = true
}
}

private func computeHashes(_ value: T) -> [Int] {
return hashFunctions.map() { hashFunc in abs(hashFunc(value) % array.count) }
}

``````public func query(_ value: T) -> Bool {
let hashValues = computeHashes(value)
let results = hashValues.map() { hashValue in array[hashValue] }
let exists = results.reduce(true, { \$0 && \$1})
return exist
}

#### 哈希集合

``````public struct HashSet<T: Hashable> {
fileprivate var dictionary = Dictionary<T, Bool>()

public init() {

}

public mutating func insert(_ element: T) {
dictionary[element] = true
}

public mutating func remove(_ element: T) {
dictionary[element] = nil
}

public func contains(_ element: T) -> Bool {
return dictionary[element] != nil
}

public func allElements() -> [T] {
return Array(dictionary.keys)
}

public var count: Int {
return dictionary.count
}

public var isEmpty: Bool {
return dictionary.isEmpty
}
}

``````extension HashSet {
public func union(_ otherSet: HashSet<T>) -> HashSet<T> {
var combined = HashSet<T>()
for obj in self.dictionary.keys {
combined.insert(obj)
}
for obj in otherSet.dictionary.keys {
combined.insert(obj)
}
return combined
}
}

``````extension HashSet {
public func intersect(_ otherSet: HashSet<T>) -> HashSet<T> {
var common = HashSet<T>()
for obj in dictionary.keys {
if otherSet.contains(obj) {
common.insert(obj)
}
}
return common
}
}

A - B

``````extension HashSet {
public func difference(_ otherSet: HashSet<T>) -> HashSet<T> {
var diff = HashSet<T>()
for obj in dictionary.keys {
if !otherSet.contains(obj) {
diff.insert(obj)
}
}
return diff
}
}

#### 多重集

``````var set = Multiset<Int>()
set.add(1) // set is now [1]
set.add(2) // set is now [1, 2]
set.add(2) // set is now [1, 2, 2]

• 顺序：数组维护添加到它的项的顺序，多重集合没有
• 测试成员资格：测试元素是否是其成员，数组是`O(n)`，多重集合是`O(1)`
• 测试子集：测试集合X是否是集合Y的子集，对于多重集而言是一个简单的操作，但对于数组来说是复杂的。

``````public struct Multiset<Element: Hashable> {
private var storage: [Element: UInt] = [:]

public init() {}
}

``````public mutating func add (_ elem: Element) {
storage[elem, default: 0] += 1
}

``````public mutating func remove(_ elem: Element) {
if let currentCount = storage[elem] {
if currentCount > 1 {
storage[elem] = currentCount - 1
} else {
storage.removeValue(forKey: elem)
}
}
}

#### 有序集

``````let s = AppleOrderedSet<Int>()

s.insert(4, at:3)

print(s.all()) // [1, 2, -1, 4, 0]

s.set(-1, at: 0) // 已经有-1在index: 2，因此这个操作不做任何事情

print(s.all()) // [1, 2, -1, 4, 0]

s.remove(-1)

print(s.all()) // [1, 2, 4, 0]

print(s.object(at: 1)) // 2

print(s.object(at: 2)) // 4

``````var indexOfKey: [T: Int]
var objects: [T]

``````// O(1)
public func add(_ object: T) {
guard indexOfKey[object] == nil else {
return
}
objects.append(object)
indexOfKey[object] = objects.count - 1
}

``````// O(n)
public func insert(_ object: T, at index: Int) {
assert(index < objects.count, "Index should be smaller than object count")
assert(index >= 0, "Index should be bigger than 0")

guard indexOfKey[object] == nil else {
return
}

objects.insert(object, at: index)
indexOfKey[object] = index
for i in index+1..<objects.count {
indexOfKey[objects[i]] = i
}
}

``````// O(1)
public func set(_ object: T, at index: Int) {
assert(index < object.count, "Index should be smaller than object count")
assert(index >= 0, "Index should be bigger than 0")

guard indexOfKey[object] == nil else {
return
}

indexOfKey.removeValue(forKey: objects[index])
indexOfKey[object] = index
objects[index] = object
}

``````// O(n)
public func remove(_ object: T) {
guard let index = indexOfKey[object] else {
return
}
indexOfKey.removeValue(forKey: object)
objects.remove(at: index)
for i in index..<objects.count {
indexOfKey[objects[i]] = i
}
}

iOS