oxilean_std/hashset/
types.rs1use std::hash::Hash;
6
7use super::oxihashset_type::OxiHashSet;
8
9use super::functions::*;
10use std::collections::HashMap;
11
12#[derive(Clone, Debug, Default)]
16pub struct Bijection<A: Eq + Hash + Clone, B: Eq + Hash + Clone> {
17 forward: std::collections::HashMap<A, B>,
18 backward: std::collections::HashMap<B, A>,
19}
20impl<A: Eq + Hash + Clone, B: Eq + Hash + Clone> Bijection<A, B> {
21 pub fn new() -> Self {
23 Self {
24 forward: std::collections::HashMap::new(),
25 backward: std::collections::HashMap::new(),
26 }
27 }
28 pub fn insert(&mut self, a: A, b: B) -> bool {
30 if self.forward.contains_key(&a) || self.backward.contains_key(&b) {
31 return false;
32 }
33 self.forward.insert(a.clone(), b.clone());
34 self.backward.insert(b, a);
35 true
36 }
37 pub fn forward(&self, a: &A) -> Option<&B> {
39 self.forward.get(a)
40 }
41 pub fn backward(&self, b: &B) -> Option<&A> {
43 self.backward.get(b)
44 }
45 pub fn len(&self) -> usize {
47 self.forward.len()
48 }
49 pub fn is_empty(&self) -> bool {
51 self.forward.is_empty()
52 }
53 pub fn remove(&mut self, a: &A) -> Option<B> {
55 if let Some(b) = self.forward.remove(a) {
56 self.backward.remove(&b);
57 Some(b)
58 } else {
59 None
60 }
61 }
62}
63#[allow(dead_code)]
65pub struct BloomFilterExt {
66 bit_array: Vec<bool>,
67 hash_count: usize,
68 expected_insertions: usize,
69 false_positive_rate: f64,
70}
71#[allow(dead_code)]
73pub struct PowerSetExt<T: Eq + std::hash::Hash + Clone> {
74 base: OxiHashSet<T>,
75 cardinality_bound: usize,
77}
78#[derive(Clone, Debug, PartialEq, Eq, Default)]
80pub struct MultiSet<T: Eq + Hash + Clone> {
81 counts: std::collections::HashMap<T, usize>,
82}
83impl<T: Eq + Hash + Clone> MultiSet<T> {
84 pub fn new() -> Self {
86 Self {
87 counts: std::collections::HashMap::new(),
88 }
89 }
90 pub fn insert(&mut self, elem: T) {
92 *self.counts.entry(elem).or_insert(0) += 1;
93 }
94 pub fn remove_one(&mut self, elem: &T) -> usize {
96 if let Some(c) = self.counts.get_mut(elem) {
97 if *c > 1 {
98 *c -= 1;
99 *c
100 } else {
101 self.counts.remove(elem);
102 0
103 }
104 } else {
105 0
106 }
107 }
108 pub fn count(&self, elem: &T) -> usize {
110 self.counts.get(elem).copied().unwrap_or(0)
111 }
112 pub fn total(&self) -> usize {
114 self.counts.values().sum()
115 }
116 pub fn distinct_count(&self) -> usize {
118 self.counts.len()
119 }
120 pub fn to_set(&self) -> OxiHashSet<T> {
122 OxiHashSet::from_iter(self.counts.keys().cloned())
123 }
124 pub fn is_empty(&self) -> bool {
126 self.counts.is_empty()
127 }
128 pub fn clear(&mut self) {
130 self.counts.clear();
131 }
132 pub fn contains(&self, elem: &T) -> bool {
134 self.counts.contains_key(elem)
135 }
136}
137#[allow(dead_code)]
139pub struct SetLatticeExt<T: Eq + std::hash::Hash + Clone> {
140 universe: OxiHashSet<T>,
141 bottom: OxiHashSet<T>,
142 top: OxiHashSet<T>,
143}
144#[derive(Clone, Debug)]
146pub struct UnionFind {
147 parent: Vec<usize>,
148 rank: Vec<usize>,
149}
150impl UnionFind {
151 pub fn new(n: usize) -> Self {
153 Self {
154 parent: (0..n).collect(),
155 rank: vec![0; n],
156 }
157 }
158 pub fn find(&mut self, x: usize) -> usize {
160 if self.parent[x] != x {
161 self.parent[x] = self.find(self.parent[x]);
162 }
163 self.parent[x]
164 }
165 pub fn union(&mut self, x: usize, y: usize) -> bool {
167 let rx = self.find(x);
168 let ry = self.find(y);
169 if rx == ry {
170 return false;
171 }
172 if self.rank[rx] < self.rank[ry] {
173 self.parent[rx] = ry;
174 } else if self.rank[rx] > self.rank[ry] {
175 self.parent[ry] = rx;
176 } else {
177 self.parent[ry] = rx;
178 self.rank[rx] += 1;
179 }
180 true
181 }
182 pub fn same(&mut self, x: usize, y: usize) -> bool {
184 self.find(x) == self.find(y)
185 }
186 pub fn component_count(&mut self) -> usize {
188 let n = self.parent.len();
189 (0..n).filter(|&i| self.find(i) == i).count()
190 }
191 pub fn component_of(&mut self, x: usize) -> Vec<usize> {
193 let root = self.find(x);
194 let n = self.parent.len();
195 (0..n).filter(|&i| self.find(i) == root).collect()
196 }
197}
198#[allow(dead_code)]
200pub struct SetPartitionExt<T: Eq + std::hash::Hash + Clone> {
201 base: OxiHashSet<T>,
202 parts: Vec<OxiHashSet<T>>,
203}
204#[allow(dead_code)]
206pub struct DisjointUnionExt<T: Eq + std::hash::Hash + Clone> {
207 left: OxiHashSet<T>,
208 right: OxiHashSet<T>,
209 total_cardinality: usize,
211}