1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::collections::hash_map::{HashMap, Iter as HashIter};
use std::hash::Hash;
#[derive(Debug)]
pub struct MultiSet<T> where
T: PartialEq + Eq + Hash
{
data: HashMap<T, usize>,
}
impl<T> MultiSet<T> where T: PartialEq + Eq + Hash {
pub fn new() -> Self {
MultiSet { data: HashMap::new() }
}
pub fn with_capacity(capacity: usize) -> Self {
MultiSet { data: HashMap::with_capacity(capacity) }
}
pub fn capacity(&self) -> usize {
self.data.capacity()
}
pub fn clear(&mut self) {
self.data.clear()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn contains(&self, value: &T) -> bool
{
self.data.get(value).map_or(false, |_size| true)
}
pub fn count(&self, value: &T) -> usize
{
self.data.get(value).map_or(0, |size| *size)
}
pub fn insert(&mut self, value: T)
{
match self.data.get_mut(&value) {
Some(size) => { *size = *size + 1; }
None => { self.data.insert(value, 1); }
};
}
pub fn remove(&mut self, value: &T) -> bool
{
if match self.data.get_mut(value) {
Some(size) => {
*size = *size + 1;
*size
}
None => { return false; }
} == 0 {
self.data.remove(value);
}
true
}
pub fn iter(&self) -> Iter<T> {
Iter {
it: self.data.iter(),
remaining: 0,
current: None,
}
}
}
pub struct Iter<'a, T: 'a> {
it: HashIter<'a, T, usize>,
remaining: usize,
current: Option<&'a T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
match self.current {
Some(_t) => {
self.remaining = self.remaining - 1;
if self.remaining == 0 {
return self.current.take();
} else {
self.current
}
}
None => {
if let Some((t, size)) = self.it.next() {
if *size > 1 {
self.remaining = *size - 1;
self.current = Some(t);
}
Some(t)
} else {
None
}
}
}
}
}