libDAI
|
00001 /* This file is part of libDAI - http://www.libdai.org/ 00002 * 00003 * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 00004 * 00005 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 00006 */ 00007 00008 00011 00012 00013 #ifndef __defined_libdai_smallset_h 00014 #define __defined_libdai_smallset_h 00015 00016 00017 #include <vector> 00018 #include <algorithm> 00019 #include <iostream> 00020 00021 00022 namespace dai { 00023 00024 00026 00030 template <typename T> 00031 class SmallSet { 00032 private: 00034 std::vector<T> _elements; 00035 00036 public: 00038 00039 00040 SmallSet() : _elements() {} 00041 00043 SmallSet( const T &t ) : _elements() { 00044 _elements.push_back( t ); 00045 } 00046 00048 SmallSet( const T &t1, const T &t2 ) { 00049 if( t1 < t2 ) { 00050 _elements.push_back( t1 ); 00051 _elements.push_back( t2 ); 00052 } else if( t2 < t1 ) { 00053 _elements.push_back( t2 ); 00054 _elements.push_back( t1 ); 00055 } else 00056 _elements.push_back( t1 ); 00057 } 00058 00060 00066 template <typename TIterator> 00067 SmallSet( TIterator begin, TIterator end, size_t sizeHint ) { 00068 _elements.reserve( sizeHint ); 00069 _elements.insert( _elements.begin(), begin, end ); 00070 std::sort( _elements.begin(), _elements.end() ); 00071 typename std::vector<T>::iterator new_end = std::unique( _elements.begin(), _elements.end() ); 00072 _elements.erase( new_end, _elements.end() ); 00073 } 00075 00077 00078 00079 SmallSet& insert( const T& t ) { 00080 typename SmallSet<T>::iterator it = std::lower_bound( _elements.begin(), _elements.end(), t ); 00081 if( (it == _elements.end()) || (*it != t) ) 00082 _elements.insert( it, t ); 00083 return *this; 00084 } 00085 00087 SmallSet& erase( const T& t ) { 00088 return (*this /= t); 00089 } 00090 00092 SmallSet operator/ ( const SmallSet& x ) const { 00093 SmallSet res; 00094 std::set_difference( _elements.begin(), _elements.end(), x._elements.begin(), x._elements.end(), inserter( res._elements, res._elements.begin() ) ); 00095 return res; 00096 } 00097 00099 SmallSet operator| ( const SmallSet& x ) const { 00100 SmallSet res; 00101 std::set_union( _elements.begin(), _elements.end(), x._elements.begin(), x._elements.end(), inserter( res._elements, res._elements.begin() ) ); 00102 return res; 00103 } 00104 00106 SmallSet operator& ( const SmallSet& x ) const { 00107 SmallSet res; 00108 std::set_intersection( _elements.begin(), _elements.end(), x._elements.begin(), x._elements.end(), inserter( res._elements, res._elements.begin() ) ); 00109 return res; 00110 } 00111 00113 SmallSet& operator/= ( const SmallSet& x ) { 00114 return (*this = (*this / x)); 00115 } 00116 00118 SmallSet& operator/= ( const T &t ) { 00119 typename std::vector<T>::iterator pos = lower_bound( _elements.begin(), _elements.end(), t ); 00120 if( pos != _elements.end() ) 00121 if( *pos == t ) // found element, delete it 00122 _elements.erase( pos ); 00123 return *this; 00124 } 00125 00127 SmallSet& operator|= ( const SmallSet& x ) { 00128 return( *this = (*this | x) ); 00129 } 00130 00132 SmallSet& operator|= ( const T& t ) { 00133 typename std::vector<T>::iterator pos = lower_bound( _elements.begin(), _elements.end(), t ); 00134 if( pos == _elements.end() || *pos != t ) // insert it 00135 _elements.insert( pos, t ); 00136 return *this; 00137 } 00138 00140 SmallSet& operator&= ( const SmallSet& x ) { 00141 return (*this = (*this & x)); 00142 } 00143 00145 bool operator<< ( const SmallSet& x ) const { 00146 return std::includes( x._elements.begin(), x._elements.end(), _elements.begin(), _elements.end() ); 00147 } 00148 00150 bool operator>> ( const SmallSet& x ) const { 00151 return std::includes( _elements.begin(), _elements.end(), x._elements.begin(), x._elements.end() ); 00152 } 00154 00156 00157 00158 bool intersects( const SmallSet& x ) const { 00159 return( (*this & x).size() > 0 ); 00160 } 00161 00163 bool contains( const T &t ) const { 00164 return std::binary_search( _elements.begin(), _elements.end(), t ); 00165 } 00166 00168 typename std::vector<T>::size_type size() const { return _elements.size(); } 00169 00171 bool empty() const { return _elements.size() == 0; } 00172 00174 std::vector<T>& elements() { return _elements; } 00175 00177 const std::vector<T>& elements() const { return _elements; } 00179 00181 typedef typename std::vector<T>::const_iterator const_iterator; 00183 typedef typename std::vector<T>::iterator iterator; 00185 typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator; 00187 typedef typename std::vector<T>::reverse_iterator reverse_iterator; 00188 00190 00191 00192 iterator begin() { return _elements.begin(); } 00194 const_iterator begin() const { return _elements.begin(); } 00195 00197 iterator end() { return _elements.end(); } 00199 const_iterator end() const { return _elements.end(); } 00200 00202 reverse_iterator rbegin() { return _elements.rbegin(); } 00204 const_reverse_iterator rbegin() const { return _elements.rbegin(); } 00205 00207 reverse_iterator rend() { return _elements.rend(); } 00209 const_reverse_iterator rend() const { return _elements.rend(); } 00210 00212 T& front() { return _elements.front(); } 00214 const T& front() const { return _elements.front(); } 00215 00217 T& back() { return _elements.back(); } 00219 const T& back() const { return _elements.back(); } 00221 00223 00224 00225 friend bool operator==( const SmallSet &a, const SmallSet &b ) { 00226 return (a._elements == b._elements); 00227 } 00228 00230 friend bool operator!=( const SmallSet &a, const SmallSet &b ) { 00231 return !(a._elements == b._elements); 00232 } 00233 00235 friend bool operator<( const SmallSet &a, const SmallSet &b ) { 00236 return a._elements < b._elements; 00237 } 00239 00241 00242 00243 friend std::ostream& operator << ( std::ostream& os, const SmallSet& x ) { 00244 os << "{"; 00245 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ ) 00246 os << (it != x.begin() ? ", " : "") << *it; 00247 os << "}"; 00248 return os; 00249 } 00251 }; 00252 00253 00254 } // end of namespace dai 00255 00256 00257 #endif