Skip to content

Commit 23770dd

Browse files
author
Simon Whitaker
committed
Add Multiset
1 parent 077c808 commit 23770dd

File tree

6 files changed

+128
-1
lines changed

6 files changed

+128
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//: Playground - noun: a place where people can play
2+
3+
#if swift(>=4.0)
4+
print("Hello, Swift 4!")
5+
#endif
6+
7+
import Cocoa
8+
9+
var set = Multiset<String>()
10+
11+
set.add("Foo")
12+
set.add("Foo")
13+
set.add("Bar")
14+
set.add("Baz")
15+
16+
set.count
17+
set.count(for: "Foo")
18+
19+
set.allItems()
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//
2+
// Multiset.swift
3+
// Multiset
4+
//
5+
// Created by Simon Whitaker on 28/08/2017.
6+
//
7+
8+
import Foundation
9+
10+
public struct Multiset<T: Hashable> {
11+
fileprivate var storage: Dictionary<T, Int>
12+
private var _count: Int = 0
13+
14+
public init() {
15+
storage = Dictionary<T, Int>()
16+
}
17+
18+
public mutating func add (_ elem: T) {
19+
if let currentCount = self.storage[elem] {
20+
self.storage[elem] = currentCount + 1;
21+
} else {
22+
self.storage[elem] = 1
23+
}
24+
_count += 1
25+
}
26+
27+
public mutating func remove (_ elem: T) {
28+
if let currentCount = self.storage[elem] {
29+
if currentCount > 1 {
30+
self.storage[elem] = currentCount - 1
31+
} else {
32+
self.storage.removeValue(forKey: elem)
33+
}
34+
_count -= 1
35+
}
36+
}
37+
38+
public func isSubSet (of superset: Multiset<T>) -> Bool {
39+
for (key, count) in self.storage {
40+
let supersetcount = superset.storage[key] ?? 0
41+
if count > supersetcount {
42+
return false
43+
}
44+
}
45+
return true
46+
}
47+
48+
public var count: Int {
49+
get {
50+
return _count
51+
}
52+
}
53+
54+
public func count(for key: T) -> Int {
55+
return self.storage[key] ?? 0
56+
}
57+
58+
public func allItems() -> [T] {
59+
var result = Array<T>()
60+
for (key, count) in self.storage {
61+
for _ in 0 ..< count {
62+
result.append(key)
63+
}
64+
}
65+
return result
66+
}
67+
}
68+
69+
extension Multiset: Equatable {
70+
public static func == (lhs: Multiset<T>, rhs: Multiset<T>) -> Bool {
71+
if lhs.storage.count != rhs.storage.count {
72+
return false
73+
}
74+
for (lkey, lcount) in lhs.storage {
75+
let rcount = rhs.storage[lkey] ?? 0
76+
if lcount != rcount {
77+
return false
78+
}
79+
}
80+
return true
81+
}
82+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='macos'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>

Multiset/README.markdown

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# An implementation of the multiset data stucture
2+
3+
## Usage
4+
5+
``` swift
6+
var b = Multiset<Character>();
7+
for c in "hello".characters {
8+
b.add(c)
9+
}
10+
let count = b.count // count is 5
11+
let lcount = b.count(for: "l") // lcount is 2
12+
```

README.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ Most of the time using just the built-in `Array`, `Dictionary`, and `Set` types
172172

173173
- [Bloom Filter](Bloom%20Filter/). A constant-memory data structure that probabilistically tests whether an element is in a set.
174174
- [Hash Set](Hash%20Set/). A set implemented using a hash table.
175-
- Multiset
175+
- [Multiset](Multiset/). A set where the number of times an element is added matters. (Also known as a bag.)
176176
- [Ordered Set](Ordered%20Set/). A set where the order of items matters.
177177

178178
### Graphs

swift-algorithm-club.xcworkspace/contents.xcworkspacedata

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)