SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
|
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