NRP Core  1.4.1
set_ops.hpp
Go to the documentation of this file.
1 #ifndef SET_OPS_H_
2 #define SET_OPS_H_
3 
4 #include <set>
5 #include <algorithm>
6 
7 using namespace std;
8 
9 template <class T>
10 bool operator==(const std::set<T> &A, const std::set<T> &B)
11 {
12 
13  if (A.size() != B.size())
14  return false;
15 
16  // both set are of equal size.
17  // check element by element
18  typedef typename std::set<T>::const_iterator set_iter;
19 
20  set_iter pA = A.begin();
21  set_iter pB = B.begin();
22  for ( ; pA != A.end(); pA++, pB++)
23  {
24  if (*pA != *pB)
25  return false;
26  }
27  return true;
28 }
29 
30 
31 template <class T>
32 std::set<T> operator*(const std::set<T> &A, const std::set<T> &B)
33 {
34  std::set<T> res;
35 
36  std::set_intersection(A.begin(), A.end(), B.begin(), B.end(),
37  inserter(res, res.begin()));
38 
39  return res;
40 }
41 
42 
43 template <class T>
44 std::set<T> & operator+=(std::set<T> &A, const std::set<T> &B)
45 {
46  // A.insert(B.begin(), B.end());
47  for (typename std::set<T>::const_iterator p=B.begin(); p!=B.end(); p++)
48  A.insert(*p);
49 
50  return A;
51 }
52 
53 template <class T>
54 std::set<T> & operator-=(std::set<T> &A, const std::set<T> &B)
55 {
56  // A.erase(B.begin(), B.end());
57  for (typename std::set<T>::const_iterator p = B.begin(); p!=B.end(); p++)
58  A.erase(*p);
59 
60  return A;
61 }
62 
63 
67 template <class T>
68 std::set<T> operator+(const std::set<T> &A, const std::set<T> &B)
69 {
70  std::set<T> res;
71 
72  std::set_union(A.begin(), A.end(), B.begin(), B.end(),
73  inserter(res, res.begin()));
74 
75  return res;
76 }
77 
78 
82 template <class T>
83 std::set<T> operator-(const std::set<T> &A, const std::set<T> &B)
84 {
85  std::set<T> res;
86 
87  std::set_difference(A.begin(), A.end(), B.begin(), B.end(),
88  inserter(res, res.begin()));
89 
90  return res;
91 }
92 
93 
99 template <class T>
100 std::set<T> symm_diff(const std::set<T> &A, const std::set<T> &B)
101 {
102  std::set<T> res;
103 
104  std::set_symmetric_difference(A.begin(), A.end(), B.begin(), B.end(),
105  inserter(res, res.begin()));
106 
107  return res;
108 }
109 
114 template <class T, class constT>
115 inline bool includes_elm( const std::set<T> &A, constT & a)
116 {
117  return ( (A.find(a) != A.end()) ?
118  true : false );
119 }
120 
121 
122 // NOTE: This algorithm asuumes the std::set is ordered.
123 // It runs in O(n+m) steps.
124 //
125 // this is an optimzied version of intersect which
126 // merely *counts* the size of the intersection,
127 // rather than explicitly create it. (Saves a lot
128 // needless copying of elements.)
129 //
130 // NOTE: if m >> n, then use big_small_intersection_size below.
131 
132 // NOTE: the O(n+m) algorithm works best if m and n are
133 // approximately equal. If one is much bigger than the other,
134 // then a better approach is to look each element of the smaller
135 // set individually. This runs in O(n log m), where m >> n.
136 //
137 template <class T>
138 int intersection_size( const std::set<T> &A, const std::set<T> &B)
139 {
140  int res = 0;
141 
142  typename std::set<T>::const_iterator first1 = A.begin(),
143  last1 = A.end(),
144  first2 = B.begin(),
145  last2 = B.end();
146 
147  for (; first1 != last1 && first2 != last2 ;)
148  {
149  if ( *first1 < *first2)
150  ++first1;
151  else if ( *first2 < *first1 )
152  ++first2;
153  else
154  {
155  ++res;
156  ++first1;
157  ++first2;
158  }
159  }
160 
161  return res;
162 }
163 
164 // This is a version of set intersection that is optimized
165 // for the case where m >> n. It runs in O(n log m), rather
166 // than O(n+m) steps.
167 //
168 // It is assumed that A is the much larger set.
169 //
170 template <class T>
171 int big_small_intersection_size( const std::set<T> &A, const std::set<T> &B)
172 {
173  int res = 0;
174  typename std::set<T>::const_iterator first=B.begin(), last=B.end();
175  for(; first != last; first++)
176  {
177  if (includes_elm(A, *first)) res++;
178  }
179  return res;
180 }
181 
182 
183 // NOTE: This algorithm asuumes the std::set is ordered.
184 // It runs in O(n+m) steps.
185 //
186 // this is an optimzied version of Union which
187 // merely *counts* the size of the std::set union,
188 // rather than explicitly create it. (Saves a lot
189 // needless copying of elements.)
190 //
191 template <class T>
192 int union_size( const std::set<T> &A, const std::set<T> &B)
193 {
194  int res = 0;
195 
196  typename std::set<T>::const_iterator first1 = A.begin(),
197  last1 = A.end(),
198  first2 = B.begin(),
199  last2 = B.end();
200 
201  for (; first1 != last1 && first2 != last2 ;)
202  {
203  if ( *first1 < *first2)
204  {
205  ++res;
206  ++first1;
207  }
208  else if ( *first2 < *first1 )
209  {
210  ++res;
211  ++first2;
212  }
213  else
214  {
215  ++res;
216  ++first1;
217  ++first2;
218  }
219  }
220 
221  return res;
222 }
223 
224 template <class T>
225 int set_difference_size( const std::set<T> &A, const std::set<T> &B)
226 {
227 
228  return (A.size() - intersection_size(A,B)) ;
229 }
230 
231 #endif
232 // SET_OPS_H_
union_size
int union_size(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:192
operator==
bool operator==(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:10
big_small_intersection_size
int big_small_intersection_size(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:171
operator+=
std::set< T > & operator+=(std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:44
set_difference_size
int set_difference_size(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:225
operator-=
std::set< T > & operator-=(std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:54
operator-
std::set< T > operator-(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:83
operator*
std::set< T > operator*(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:32
intersection_size
int intersection_size(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:138
symm_diff
std::set< T > symm_diff(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:100
includes_elm
bool includes_elm(const std::set< T > &A, constT &a)
Definition: set_ops.hpp:115
operator+
std::set< T > operator+(const std::set< T > &A, const std::set< T > &B)
Definition: set_ops.hpp:68