00001
00008 #ifndef __LIGHT_VECTOR_SET_INTERSECTION__
00009 #define __LIGHT_VECTOR_SET_INTERSECTION__ t
00010
00011 #include "common/debug.hpp"
00012 #include "LightVector.hpp"
00013
00026 template <bool EARLY_FILTERING, class TYPE>
00027 inline
00028 bool set_intersection(LightVector<TYPE>& result, const LightVector<TYPE>& x, const LightVector<TYPE>& y, const int minimalSize = 0) {
00029 assert(x.size() > 0);
00030 assert(y.size() > 0);
00031 assert(minimalSize <= x.size());
00032 assert(minimalSize <= y.size());
00033 assert(! EARLY_FILTERING || minimalSize >= 2);
00034
00035 assert(&result != &x);
00036 assert(&result != &y);
00037
00038 assert(result.capacity() >= minimalSize || result.capacity() >= x.size() || result.capacity() >= y.size());
00039 assert(EARLY_FILTERING || result.capacity() >= x.size() || result.capacity() >= y.size());
00040
00041
00042
00043
00044 typename LightVector<TYPE>::const_iterator iterx = x.begin(), itery = y.begin(), endx = x.end(), endy = y.end();
00045 typename LightVector<TYPE>::iterator iterResult = result.beginUnbounded();
00046
00047
00048 if (EARLY_FILTERING && minimalSize > 1) {
00049 endx -= minimalSize - 1;
00050 endy -= minimalSize - 1;
00051 }
00052
00053
00054 typename LightVector<TYPE>::iterator minimalResult = iterResult + minimalSize;
00055 int itemx = *iterx;
00056 int itemy = *itery;
00057
00058
00059 while (true) {
00060 if (itemx < itemy) {
00061 ++iterx; if (iterx == endx) break;
00062 itemx = *iterx;
00063 } else if (itemx > itemy) {
00064 ++itery; if (itery == endy) break;
00065 itemy = *itery;
00066 } else {
00067 *iterResult++ = itemx;
00068 if (EARLY_FILTERING && iterResult < minimalResult) {
00069 ++endx;
00070 ++endy;
00071 }
00072 ++iterx; if (iterx == endx) break;
00073 ++itery; if (itery == endy) break;
00074 itemx = *iterx; itemy = *itery;
00075 }
00076 }
00077
00078 result.resizeToEndOf(iterResult);
00079
00080 return result.size() >= minimalSize;
00081 }
00082
00092 template <bool EARLY_FILTERING, class TYPE>
00093 inline
00094 int cardinality_of_set_intersection(const LightVector<TYPE>& x, const LightVector<TYPE>& y, const int minimalSize = 0) {
00095 assert(x.size() > 0);
00096 assert(y.size() > 0);
00097 assert(minimalSize <= x.size());
00098 assert(minimalSize <= y.size());
00099 assert(! EARLY_FILTERING || minimalSize >= 2);
00100
00101
00102
00103
00104 typename LightVector<TYPE>::const_iterator iterx = x.begin(), itery = y.begin(), endx = x.end(), endy = y.end();
00105
00106
00107 if (EARLY_FILTERING && minimalSize > 1) {
00108 endx -= minimalSize - 1;
00109 endy -= minimalSize - 1;
00110 }
00111
00112
00113 int itemx = *iterx;
00114 int itemy = *itery;
00115 int resultSize = 0;
00116
00117
00118 while (true) {
00119 if (itemx < itemy) {
00120 ++iterx; if (iterx == endx) break;
00121 itemx = *iterx;
00122 } else if (itemx > itemy) {
00123 ++itery; if (itery == endy) break;
00124 itemy = *itery;
00125 } else {
00126 ++resultSize;
00127 if (EARLY_FILTERING && resultSize < minimalSize) {
00128 ++endx;
00129 ++endy;
00130 }
00131 ++iterx; if (iterx == endx) break;
00132 ++itery; if (itery == endy) break;
00133 itemx = *iterx; itemy = *itery;
00134 }
00135 }
00136
00137 if (resultSize < minimalSize)
00138 resultSize = 0;
00139
00140 return resultSize;
00141 }
00142
00143
00144 #endif