【譯】Swift算法俱樂部-多重集合

本文是對 Swift Algorithm Club 翻譯的一篇文章。 Swift Algorithm Clubraywenderlich.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]
複製代碼

你可能會認爲這看起來很像一個數組。 那你爲何要用多重集呢? 讓咱們考慮二者之間的差別......數據結構

  • 排序:數組維護添加到它們的項目的順序,多重集合沒有
  • 測試成員資格:測試元素是否其成員,數組是O(N),而多重集合的O(1)。
  • 測試子集:測試集合X是不是集合Y的子集,對於多重集而言是一個簡單的操做,但對於數組來講是複雜的

多重集的典型操做是:學習

  • 添加元素
  • 刪除元素
  • 獲取元素的計數(添加的次數)
  • 獲取整個集合的計數(已添加的項數)
  • 檢查它是不是另外一個多重集的子集

在實際使用中,可以使用多重集合來肯定一個字符串是不是另外一個字符串的部分。例如,「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
}
複製代碼

做者:Simon Whitaker
翻譯:Andy Ron
校對:Andy Ron

相關文章
相關標籤/搜索