本文是對 Swift Algorithm Club 翻譯的一篇文章。 Swift Algorithm Club是 raywenderlich.com網站出品的用Swift實現算法和數據結構的開源項目,目前在GitHub上有18000+⭐️,我初略統計了一下,大概有一百左右個的算法和數據結構,基本上常見的都包含了,是iOSer學習算法和數據結構不錯的資源。 🐙andyRon/swift-algorithm-club-cn是我對Swift Algorithm Club,邊學習邊翻譯的項目。因爲能力有限,如發現錯誤或翻譯不妥,請指正,歡迎pull request。也歡迎有興趣、有時間的小夥伴一塊兒參與翻譯和學習🤓。固然也歡迎加⭐️,🤩🤩🤩🤨🤪。 本文的翻譯原文和代碼能夠查看🐙swift-algorithm-club-cn/Multisetgit
多重集合(Multiset)github
多重集合(也稱爲bag,簡稱多重集)是一種相似於常規集的數據結構,但它能夠存儲同一元素的多個實例。算法
例如,若是我將元素1,2,2添加到常規集中,則該集將僅包含兩個項,由於第二次添加2無效。swift
var set = Set<Int>()
set.add(1) // set is now [1]
set.add(2) // set is now [1, 2]
set.add(2) // set is still [1, 2]
複製代碼
相比之下,在將元素1,2,2添加到多重集以後,它將包含三個項目。數組
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]
複製代碼
你可能會認爲這看起來很像一個數組。 那你爲何要用多重集呢? 讓咱們考慮二者之間的差別......數據結構
多重集的典型操做是:學習
在實際使用中,可以使用多重集合來肯定一個字符串是不是另外一個字符串的部分。例如,「cacti」這個詞是「tactical」的部分。(換句話說,我能夠從新整理「tactical」字母來獲得「cacti」,以及餘下的一些字母。)測試
var cacti = Multiset<Character>("cacti")
var tactical = Multiset<Character>("tactical")
cacti.isSubSet(of: tactical) // true!
複製代碼
在幕後,Multiset的實現使用字典來存儲元素到它們被添加的次數的映射。網站
這是它的本質:spa
public struct Multiset<Element: Hashable> {
private var storage: [Element: UInt] = [:]
public init() {}
複製代碼
如下是如何使用此類建立多重集的字符串:
var set = Multiset<String>()
複製代碼
添加元素是遞增該元素的計數器,或者若是它尚不存在則將其設置爲1:
public mutating func add (_ elem: Element) {
storage[elem, default: 0] += 1
}
複製代碼
如下是使用此方法添加到咱們以前建立的集合的方法:
set.add("foo")
set.add("foo")
set.allItems // returns ["foo", "foo"]
複製代碼
咱們的集合如今包含兩個元素,字符串「foo」。
刪除元素與添加元素的工做方式大體相同; 遞減元素的計數器,或者若是在刪除以前其值爲1,則將其從基礎字典中刪除。
public mutating func remove (_ elem: Element) {
if let currentCount = storage[elem] {
if currentCount > 1 {
storage[elem] = currentCount - 1
} else {
storage.removeValue(forKey: elem)
}
}
}
複製代碼
獲取項目的計數很簡單:咱們只返回內部字典中給定項目的值。
public func count(for key: Element) -> UInt {
return storage[key] ?? 0
}
複製代碼