-
Notifications
You must be signed in to change notification settings - Fork 4
/
SET.h
234 lines (211 loc) · 6.85 KB
/
SET.h
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#ifndef CH3_SET_H
#define CH3_SET_H
#include <set>
#include <stdexcept>
#include <ostream>
#include <sstream>
using std::set;
using std::runtime_error;
using std::ostream;
using std::ostringstream;
/**
* The {@code SET} class represents an ordered set of comparable keys.
* It supports the usual <em>add</em>, <em>contains</em>, and <em>delete</em>
* methods. It also provides ordered methods for finding the <em>minimum</em>,
* <em>maximum</em>, <em>floor</em>, and <em>ceiling</em> and set methods
* for <em>union</em>, <em>intersection</em>, and <em>equality</em>.
* <p>
* Even though this implementation include the method {@code equals()}, it
* does not support the method {@code hashCode()} because sets are mutable.
* <p>
* This implementation uses a balanced binary search tree. It requires that
* the key type implements the {@code Comparable} interface and calls the
* {@code compareTo()} and method to compare two keys. It does not call either
* {@code equals()} or {@code hashCode()}.
* The <em>add</em>, <em>contains</em>, <em>delete</em>, <em>minimum</em>,
* <em>maximum</em>, <em>ceiling</em>, and <em>floor</em> methods take
* logarithmic time in the worst case.
* The <em>size</em>, and <em>is-empty</em> operations take constant time.
* Construction takes constant time.
* <p>
* For additional documentation, see
* <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
* <i>Algorithms in Java, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*
* @param <Key> the generic type of a key in this set
*/
template<typename Key>
class SET {
public:
/**
* Initializes an empty set.
*/
SET() { set_obj.clear(); }
/**
* Initializes a new set that is an independent copy of the specified set.
*
* @param x the set to copy
*/
SET(const SET<Key> &x) : set_obj(x.set_obj) {}
/**
* Adds the key to this set (if it is not already present).
*
* @param key the key to add
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
void add(Key key) {
set_obj.insert(key);
}
/**
* Returns true if this set contains the given key.
*
* @param key the key
* @return {@code true} if this set contains {@code key};
* {@code false} otherwise
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
bool contains(Key key) {
return set_obj.find(key) != set_obj.end();
}
/**
* Removes the specified key from this set (if the set contains the specified key).
*
* @param key the key
* @throws IllegalArgumentException if {@code key} is {@code null}
*/
void delete_op(Key key) {
set_obj.erase(key);
}
/**
* Returns the number of keys in this set.
*
* @return the number of keys in this set
*/
int size() {
return set_obj.size();
}
/**
* Returns true if this set is empty.
*
* @return {@code true} if this set is empty;
* {@code false} otherwise
*/
bool isEmpty() {
return set_obj.empty();
}
/**
* Returns the largest key in this set.
*
* @return the largest key in this set
* @throws NoSuchElementException if this set is empty
*/
Key max() {
if (isEmpty()) throw runtime_error("called max() with empty set");
return *(--set_obj.end());
}
/**
* Returns the smallest key in this set.
*
* @return the smallest key in this set
* @throws NoSuchElementException if this set is empty
*/
Key min() {
if (isEmpty()) throw runtime_error("called min() with empty set");
return *(set_obj.begin());
}
/**
* Returns the smallest key in this set greater than or equal to {@code key}.
*
* @param key the key
* @return the smallest key in this set greater than or equal to {@code key}
* @throws IllegalArgumentException if {@code key} is {@code null}
* @throws NoSuchElementException if there is no such key
*/
Key ceiling(Key key) {
auto k = set_obj.lower_bound(key);
if (k == set_obj.end()) throw runtime_error("all keys are less than this key");
return *k;
}
/**
* Returns the largest key in this set less than or equal to {@code key}.
*
* @param key the key
* @return the largest key in this set table less than or equal to {@code key}
* @throws IllegalArgumentException if {@code key} is {@code null}
* @throws NoSuchElementException if there is no such key
*/
Key floor(Key key) {
if (key < min())
throw runtime_error("all keys are greater than this key");
if (key >= max())
return max();
return *(--set_obj.lower_bound(key));
}
/**
* Returns the union of this set and that set.
*
* @param that the other set
* @return the union of this set and that set
* @throws IllegalArgumentException if {@code that} is {@code null}
*/
SET<Key> union_op(SET<Key> &that) {
SET<Key> c;
for (auto x : set_obj) {
c.add(x);
}
for (auto x : that) {
c.add(x);
}
return c;
}
/**
* Returns the intersection of this set and that set.
*
* @param that the other set
* @return the intersection of this set and that set
* @throws IllegalArgumentException if {@code that} is {@code null}
*/
SET<Key> intersects(SET<Key> &that) {
SET<Key> c;
if (size() < that.size()) {
for (Key x : set_obj) {
if (that.contains(x)) c.add(x);
}
} else {
for (auto x : that) {
if (contains(x)) c.add(x);
}
}
return c;
}
/**
* Returns all of the keys in this set, as an iterator.
* To iterate over all of the keys in a set named {@code set}, use the
* foreach notation: {@code for (Key key : set)}.
*
* @return an iterator to all of the keys in this set
*/
typename set<Key>::iterator begin() { return set_obj.begin(); }
typename set<Key>::iterator end() { return set_obj.end(); }
typename set<Key>::const_iterator begin() const { return set_obj.cbegin(); }
typename set<Key>::const_iterator end() const { return set_obj.cend(); }
/**
* Returns a string representation of this set.
*
* @return a string representation of this set, enclosed in curly braces,
* with adjacent keys separated by a comma and a space
*/
friend ostream &operator<<(ostream &stream, const SET<Key> &that) {
ostringstream ss;
for (auto k: that)
ss << k << " ";
stream << ss.str();
return stream;
}
private:
set<Key> set_obj;
};
#endif //CH3_SET_H