SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/rmq_succinct_sct.hpp
Go to the documentation of this file.
00001 /* sdsl - succinct data structures library
00002     Copyright (C) 2009 Simon Gog
00003 
00004     This program is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program.  If not, see http://www.gnu.org/licenses/ .
00016 */
00021 #ifndef INCLUDED_SDSL_RMQ_SUCCINCT_SCT
00022 #define INCLUDED_SDSL_RMQ_SUCCINCT_SCT
00023 
00024 #include "rmq_support.hpp"
00025 #include "int_vector.hpp"
00026 #include "algorithms_for_compressed_suffix_trees.hpp"
00027 #include "bp_support_sada.hpp"
00028 #include "util.hpp"
00029 
00031 namespace sdsl
00032 {
00033 
00034 
00035 template< bool Minimum = true, class Bp_support = bp_support_sada<256,32,rank_support_v5<> > >
00036 class rmq_succinct_sct;
00037 
00038 template<class Bp_support = bp_support_sada<256,32,rank_support_v5<> > >
00039 struct range_maximum_sct {
00040     typedef rmq_succinct_sct<false, Bp_support> type;
00041 };
00042 
00044 
00053 template<bool Minimum, class Bp_support>
00054 class rmq_succinct_sct
00055 {
00056         bit_vector                                      m_sct_bp;               
00057         Bp_support                                      m_sct_bp_support;       
00058 
00059                 template<class RandomAccessContainer>
00060         void construct(const RandomAccessContainer* v) {
00061             if (v == NULL) {
00062                 m_sct_bp = bit_vector(0); m_sct_bp_support = Bp_support();
00063             } else {
00064 #ifdef RMQ_SCT_BUILD_BP_NOT_SUCCINCT
00065                 // this method takes \f$n\log n\f$ bits extra space in the worst case
00066                 algorithm::construct_supercartesian_tree_bp(*v, m_sct_bp, Minimum);
00067 #else
00068                 // this method takes only \f$n\f$ bits extra space in all cases
00069                 algorithm::construct_supercartesian_tree_bp_succinct(*v, m_sct_bp, Minimum);
00070                 //  TODO: constructor which uses int_vector_file_buffer
00071 #endif
00072                 m_sct_bp_support = Bp_support(&m_sct_bp);
00073             }
00074         }
00075 
00076         void copy(const rmq_succinct_sct& rm) {
00077             m_sct_bp = rm.m_sct_bp;
00078             m_sct_bp_support = rm.m_sct_bp_support;
00079             m_sct_bp_support.set_vector(&m_sct_bp);
00080         }
00081 
00082     public:
00083         typedef typename bit_vector::size_type size_type;
00084         typedef typename bit_vector::size_type value_type;
00085 
00086         const bit_vector& sct_bp;
00087         const Bp_support& sct_bp_support;
00088 
00090                 rmq_succinct_sct() : sct_bp(m_sct_bp), sct_bp_support(m_sct_bp_support) {}
00091 
00093                 template<class RandomAccessContainer>
00094         rmq_succinct_sct(const RandomAccessContainer* v=NULL): sct_bp(m_sct_bp), sct_bp_support(m_sct_bp_support) {
00095             construct(v);
00096         }
00097 
00099         rmq_succinct_sct(const rmq_succinct_sct& rm): sct_bp(m_sct_bp), sct_bp_support(m_sct_bp_support) {
00100             if (this != &rm) { // if v is not the same object
00101                 copy(rm);
00102             }
00103         }
00104 
00106         ~rmq_succinct_sct() { }
00107 
00108         rmq_succinct_sct& operator=(const rmq_succinct_sct& rm) {
00109             if (this != &rm) {
00110                 copy(rm);
00111             }
00112             return *this;
00113         }
00114 
00115         void swap(const rmq_succinct_sct& rm) {
00116                         m_sct_bp.swap(rm.m_sct_bp);
00117                         util::swap_support(m_sct_bp_support, rm.m_sct_bp_support, &m_sct_bp, &(rm.m_sct_bp));
00118         }
00119 
00121 
00131         size_type operator()(const size_type l, const size_type r)const {
00132             assert(l <= r); assert(r < size());
00133             if (l==r)
00134                 return l;
00135             size_type i         = m_sct_bp_support.select(l+1);
00136             size_type j         = m_sct_bp_support.select(r+1);
00137             size_type fc_i      = m_sct_bp_support.find_close(i);
00138             if (j < fc_i) { // i < j < find_close(j) < find_close(i)
00139                 return l;
00140             } else { // if i < find_close(i) < j < find_close(j)
00141                 size_type ec = m_sct_bp_support.rr_enclose(i,j);
00142                 if (ec == m_sct_bp_support.size()) {// no restricted enclosing pair found
00143                     return r;
00144                 } else { // found range restricted enclosing pair
00145                     return m_sct_bp_support.rank(ec)-1; // subtract 1, as the index is 0 based
00146                 }
00147             }
00148         }
00149 
00150         size_type size()const {
00151             return m_sct_bp.size()/2;
00152         }
00153 
00154         size_type serialize(std::ostream& out, structure_tree_node* v=NULL, std::string name="")const {
00155                 structure_tree_node* child = structure_tree::add_child(v, name, util::class_name(*this));
00156             size_type written_bytes = 0;
00157             written_bytes += m_sct_bp.serialize(out, child, "sct_bp");
00158             written_bytes += m_sct_bp_support.serialize(out, child, "sct_bp_support");
00159                 structure_tree::add_size(child, written_bytes);
00160             return written_bytes;
00161         }
00162 
00163         void load(std::istream& in) {
00164             m_sct_bp.load(in);
00165             m_sct_bp_support.load(in, &m_sct_bp);
00166         }
00167 };
00168 
00169 
00170 }
00171 
00172 
00173 #endif