00001 #ifndef GRAL_GB_SEQUENCE_ALGORITHMS_H
00002 #define GRAL_GB_SEQUENCE_ALGORITHMS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Utility/pre-post-conditions.h"
00019
00020 #include <iterator>
00021 #include <functional>
00022 #include <algorithm>
00023 #include <numeric>
00024
00025 namespace GrAL {
00026
00029 namespace sequence {
00030
00039 struct less_first {
00040 typedef bool result_type;
00041 template<class Pair>
00042 bool operator()(Pair const& p1, Pair const& p2) const { return p1.first < p2.first;}
00043 };
00044
00049 struct less_second {
00050 typedef bool result_type;
00051 template<class Pair>
00052 bool operator()(Pair const& p1, Pair const& p2) const { return p1.second < p2.second;}
00053 };
00054
00059 struct greater_first {
00060 typedef bool result_type;
00061 template<class Pair>
00062 bool operator()(Pair const& p1, Pair const& p2) const { return p1.first > p2.first;}
00063 };
00064
00069 struct greater_second {
00070 typedef bool result_type;
00071 template<class Pair>
00072 bool operator()(Pair const& p1, Pair const& p2) const { return p1.second > p2.second;}
00073 };
00074
00079 struct size_functor {
00080 template<class T>
00081 typename T::size_type operator()(T const& t) const { return t.size();}
00082 };
00083
00084
00089 template<class T>
00090 struct join : public std::binary_function<T,T,T> {
00091 T sep;
00092 join(T sep_ = "") : sep(sep_) {}
00093 T operator()(T const& lhs, T const& rhs)
00094 { return lhs + sep + rhs; }
00095 };
00096
00097
00098
00099
00105 template<class ForwardIterator, class Map>
00106 void compute_histogram(ForwardIterator begin, ForwardIterator end, Map & hist)
00107 {
00108 while(begin != end) {
00109 hist[*begin]++;
00110 ++begin;
00111 }
00112 }
00123 template<class ForwardIterator, class Map, class F>
00124 void compute_histogram(ForwardIterator begin, ForwardIterator end, Map & hist, F f)
00125 {
00126 while(begin != end) {
00127 hist[f(*begin)]++;
00128 ++begin;
00129 }
00130 }
00131
00132
00133
00139 template<class Map>
00140 typename Map::const_iterator arg_max_map(Map const& map)
00141 {
00142 typename Map::const_iterator it = map.begin();
00143 typename Map::const_iterator end = map.end();
00144 typename Map::const_iterator max_iter = it;
00145
00146 while(it != end) {
00147 if(max_iter->second < it->second) {
00148 max_iter = it;
00149 }
00150 ++it;
00151 }
00152 return max_iter;
00153 }
00154
00159 template <typename InputIterator, typename Predicate>
00160 inline bool exists(InputIterator first, InputIterator end, Predicate p) {
00161 while(first != end) {
00162 if(p(*first))
00163 return true;
00164 ++first;
00165 }
00166 return false;
00167 }
00172 template <typename InputIterator, typename Predicate>
00173 inline bool forall(InputIterator first, InputIterator end, Predicate p) {
00174 bool res = true;
00175 while(first != end) {
00176 res = res && p(*first);
00177 ++first;
00178 }
00179 return res;
00180 }
00181
00186 template <typename InputIterator, typename Value>
00187 inline bool contains(InputIterator first, InputIterator end, Value const& v) {
00188 return std::find(first,end,v) != end;
00189 }
00190
00191
00196 template <typename InputIterator>
00197 inline typename std::iterator_traits<InputIterator>::value_type
00198 sum(InputIterator first, InputIterator end)
00199 {
00200 typedef typename std::iterator_traits<InputIterator>::value_type value_type;
00201 return std::accumulate(first,end, value_type(0), std::plus<value_type>());
00202 }
00203
00208 template <typename InputIterator>
00209 inline typename std::iterator_traits<InputIterator>::value_type
00210 average(InputIterator first, InputIterator end)
00211 {
00212 typename std::iterator_traits<InputIterator>::value_type res = sum(first,end);
00213 return res / distance(first,end);
00214 }
00215
00219 template<class It>
00220 std::string concat(It start, It end, std::string sep = "")
00221 { return std::accumulate(start, end, sep, join<std::string>(sep));}
00222
00223
00229 template<typename ForwardIterator, typename Less>
00230 int bubble_sort(ForwardIterator begin, ForwardIterator end, Less less)
00231 {
00232 if(begin == end) return 0;
00233 ForwardIterator next = begin;
00234 ++next;
00235 if(next == end) return 0;
00236
00237 int num_transpositions = 0;
00238 bool ordered = false;
00239 while(ordered == false) {
00240 ordered = true;
00241 while(next != end) {
00242 if(! less(*begin, *next)) {
00243 ::std::swap(*begin, *next);
00244 ordered = false;
00245 ++num_transpositions;
00246 }
00247 ++begin;
00248 ++next;
00249 }
00250 }
00251 return num_transpositions;
00252 }
00253
00254 template<typename ForwardIterator>
00255 int bubble_sort(ForwardIterator begin, ForwardIterator end)
00256 { return bubble_sort(begin, end, ::std::less<typename ::std::iterator_traits<ForwardIterator>::value_type>());}
00257
00258
00265 template<typename ForwardIterator1, typename ForwardIterator2>
00266 bool same_permutation_sign(ForwardIterator1 begin1, ForwardIterator1 end1,
00267 ForwardIterator2 begin2, ForwardIterator2 end2)
00268 {
00269 int t1 = bubble_sort(begin1, end1);
00270 int t2 = bubble_sort(begin2, end2);
00271 REQUIRE(::std::equal(begin1, end1, begin2), "", 1);
00272 return (t1%2) == (t2%2);
00273 }
00274
00275
00276
00281 template<class Container>
00282 void sort_and_make_unique(Container & container)
00283 {
00284 std::sort(container.begin(), container.end());
00285 container.erase(unique(container.begin(), container.end()), container.end());
00286 }
00287
00292 template<typename ForwardIterator, typename LessOp>
00293 bool is_increasing(ForwardIterator begin, ForwardIterator end, LessOp less) {
00294 if(begin == end)
00295 return true;
00296 ForwardIterator next = begin;
00297 ++next;
00298 while(next != end) {
00299 if(!less(*begin, *next))
00300 return false;
00301 ++begin;
00302 ++next;
00303 }
00304 return true;
00305 }
00306
00313 template<typename ForwardIterator>
00314 bool is_increasing(ForwardIterator begin, ForwardIterator end)
00315 { return is_increasing(begin,end, std::less<typename std::iterator_traits<ForwardIterator>::value_type>());}
00316
00317
00323 template<class Container>
00324 bool is_increasing(Container const& container)
00325 { return is_increasing(container.begin(), container.end());}
00326
00327
00335 template<class Container, class Container2>
00336 void remove_set(Container & s, Container2 const& t)
00337 {
00338 REQUIRE(is_increasing(s), "",1);
00339 REQUIRE(is_increasing(t), "",1);
00340 Container s_new;
00341 std::set_difference(s.begin(), s.end(),
00342 t.begin(), t.end(), std::back_inserter(s_new));
00343 std::swap(s,s_new);
00344 }
00345
00349 template<class InputIt>
00350 inline InputIt next(InputIt i)
00351 { ++i; return i;}
00352
00355 template<class InputIt>
00356 inline InputIt next(InputIt i, unsigned n)
00357 {
00358 while(n > 0) {
00359 ++i;
00360 --n;
00361 }
00362 return i;
00363 }
00364
00378 template<class InputIt, class OutputIt, class Filter>
00379 inline
00380 OutputIt copy_filter(InputIt b, InputIt e, OutputIt dest, Filter f)
00381 {
00382 while( b != e) {
00383 *dest = f(*b);
00384 ++b; ++dest;
00385 }
00386 return dest;
00387 }
00388
00398 template<class FwdIt, class P1, class P2>
00399 inline
00400 FwdIt find_if_preference(FwdIt b, FwdIt e, const P1& must_be, const P2& should_be)
00401 {
00402 FwdIt found = e;
00403 while( b != e) {
00404 if(must_be(*b)) {
00405 if(should_be(*b))
00406 return b;
00407 else
00408 found = b;
00409 }
00410 ++b;
00411 }
00412 return found;
00413 }
00414
00425 template<class M1, class M2>
00426 void mapping_assign(M1& dest, M2 const& src)
00427 {
00428 typedef typename M2::domain_type dom_type;
00429 typedef typename dom_type::const_iterator dom_iter;
00430 dom_iter end = src.domain().end();
00431 for(dom_iter d = src.domain().begin(); d != end; ++d)
00432 dest[*d] = src[*d];
00433 }
00434
00435
00436 }
00437
00438 }
00439
00440
00441 #endif
00442