SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
|
00001 /* sdsl - succinct data structures library 00002 Copyright (C) 2010 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_SUFFIXARRAY_HELPER 00022 #define INCLUDED_SDSL_SUFFIXARRAY_HELPER 00023 00024 #include <stdint.h> 00025 #include <cstdlib> 00026 #include <cassert> 00027 #include "algorithms_for_compressed_suffix_arrays.hpp" 00028 #include "iterators.hpp" 00029 00030 namespace sdsl 00031 { 00032 00034 template<class CsaPsi> 00035 class psi_of_csa_psi 00036 { 00037 public: 00038 typedef typename CsaPsi::value_type value_type; 00039 typedef typename CsaPsi::size_type size_type; 00040 typedef typename CsaPsi::difference_type difference_type; 00041 typedef typename CsaPsi::enc_vector_type::const_iterator const_iterator; 00042 private: 00043 CsaPsi* m_csa; //<- pointer to the (compressed) suffix array that is based on the compressed psi function 00044 public: 00045 00047 psi_of_csa_psi(CsaPsi* csa_psi=NULL) { 00048 m_csa = csa_psi; 00049 } 00050 00052 psi_of_csa_psi(const psi_of_csa_psi& psi_of_csa) { 00053 m_csa = psi_of_csa.m_csa; 00054 } 00055 00057 00061 value_type operator[](size_type i)const { 00062 assert(m_csa != NULL); 00063 assert(i < size()); 00064 return m_csa->m_psi[i]; 00065 } 00066 00068 00071 value_type operator()(size_type i)const { 00072 // TODO: replace by \sigma binary searches on PSI function?? 00073 return (*m_csa)(((*m_csa)[i]+size()-1)%size()); // TODO:replace % by to_add table 00074 } 00075 00077 psi_of_csa_psi& operator=(const psi_of_csa_psi& psi_of_csa) { 00078 if (this != &psi_of_csa) { 00079 m_csa = psi_of_csa.m_csa; 00080 } 00081 return *this; 00082 } 00083 00085 size_type size()const { 00086 return m_csa->size(); 00087 } 00088 00090 size_type empty()const { 00091 return m_csa->empty(); 00092 } 00093 00095 void swap(psi_of_csa_psi& psi_of_csa) { 00096 if (this != &psi_of_csa) { 00097 ;// std::swap(m_csa, psi.m_csa_wt); // do not exchange the supported structure! 00098 } 00099 } 00100 00102 00105 const_iterator begin()const { 00106 return m_csa->m_psi.begin();//const_iterator(this, 0); 00107 } 00108 00110 00113 const_iterator end()const { 00114 return m_csa->m_psi.end();//const_iterator(this, size()); 00115 } 00116 00117 // Get the number of sampled \f$\Psi\f$ values. 00118 uint32_t get_sample_dens()const { 00119 return m_csa->m_psi.get_sample_dens(); 00120 } 00121 }; 00122 00124 template<class Csa> 00125 class psi_of_sa_and_isa 00126 { 00127 public: 00128 typedef typename Csa::value_type value_type; 00129 typedef typename Csa::size_type size_type; 00130 typedef typename Csa::difference_type difference_type; 00131 typedef random_access_const_iterator<psi_of_sa_and_isa> const_iterator;// STL Container requirement 00132 private: 00133 Csa* m_csa; //<- pointer to the (full text index) suffix array 00134 value_type m_size_m1; // size minus 1 00135 value_type to_add1[2], to_add2[2]; 00136 public: 00137 00139 psi_of_sa_and_isa(Csa* csa=NULL) { 00140 m_csa = csa; 00141 if (csa != NULL) 00142 m_size_m1 = m_csa->size()-1; 00143 else 00144 m_size_m1 = (size_type)-1; 00145 to_add1[0] = 1; 00146 to_add1[1] = -m_size_m1; 00147 to_add2[0] = m_size_m1; 00148 to_add2[1] = -1; 00149 } 00150 00151 // Copy constructor 00152 psi_of_sa_and_isa(const psi_of_sa_and_isa& csa) { 00153 m_csa = csa.m_csa; 00154 m_size_m1 = csa.m_size_m1; 00155 for (int i=0; i<2; ++i) { 00156 to_add1[i] = csa.to_add1[i]; 00157 to_add2[i] = csa.to_add2[i]; 00158 } 00159 } 00160 00162 00166 value_type operator[](size_type i)const { 00167 assert(m_csa!=NULL); 00168 assert(i<size()); 00169 // \f$\Psi[i] = SA^{-1}[SA[i]+1 \mod n]\f$, where \f$n\f$ is the length of the suffix array SA 00170 // return (*m_csa)( ((*m_csa)[i]+1) % m_csa->size() ); // TODO: replace % by to_add table 00171 value_type sai = (*m_csa)[i]; 00172 return (*m_csa)(sai + to_add1[ sai == m_size_m1 ]); 00173 // return (*m_csa)( (*m_csa)[i] + to_add1[ (*m_csa)[i] < m_size_m1 ] ); 00174 } 00175 00177 00180 value_type operator()(size_type i)const { 00181 assert(m_csa!=NULL); 00182 assert(i<size()); 00183 // \f$LF[i] = SA^{-1}[SA[i]-1 \mod n]\f$, where \f$n\f$ is the length of the suffix array SA 00184 // return (*m_csa)( ((*m_csa)[i]+size()-1) % size() ); //was slower than the current solution 00185 value_type sai = (*m_csa)[i]; 00186 return (*m_csa)(sai + to_add2[(bool)sai ]); 00187 } 00188 00190 psi_of_sa_and_isa& operator=(const psi_of_sa_and_isa& csa) { 00191 if (this != &csa) { 00192 m_csa = csa.m_csa; 00193 m_size_m1 = csa.m_size_m1; 00194 for (int i=0; i<2; ++i) { 00195 to_add1[i] = csa.to_add1[i]; 00196 to_add2[i] = csa.to_add2[i]; 00197 } 00198 } 00199 return *this; 00200 } 00201 00203 00205 bool operator==(const psi_of_sa_and_isa& psi)const { 00206 return true; 00207 } 00208 00210 size_type size()const { 00211 return m_csa->size(); 00212 } 00213 00215 size_type empty()const { 00216 return m_csa->empty(); 00217 } 00219 void swap(psi_of_sa_and_isa& psi) { 00220 if (this != &psi) { 00221 ;// std::swap(m_csa, psi.m_csa); // do not exchange the supported structure! 00222 std::swap(m_size_m1, psi.m_size_m1); 00223 for (int i=0; i<2; ++i) { 00224 std::swap(to_add1[i], psi.to_add1[i]); 00225 std::swap(to_add2[i], psi.to_add2[i]); 00226 } 00227 } 00228 } 00229 00231 00234 const_iterator begin()const { 00235 return const_iterator(this, 0); 00236 } 00237 00239 00242 const_iterator end()const { 00243 return const_iterator(this, size()); 00244 } 00245 00246 // Get the number of sampled \f$\Psi\f$ values. In this wrapper the number of sampled (i.e. explicitly stored) \f$\Psi\f$ values is zero. 00247 uint32_t get_sample_dens()const { 00248 return 0; 00249 } 00250 00251 }; 00252 00254 template<class CsaPsi> 00255 class bwt_of_csa_psi 00256 { 00257 public: 00258 typedef const unsigned char value_type; 00259 typedef typename CsaPsi::size_type size_type; 00260 typedef typename CsaPsi::difference_type difference_type; 00261 typedef random_access_const_iterator<bwt_of_csa_psi> const_iterator;// STL Container requirement 00262 private: 00263 CsaPsi* m_csa; //<- pointer to the (compressed) suffix array that is based on the \f$\Psi\f$ function. 00264 public: 00265 00267 bwt_of_csa_psi(CsaPsi* csa=NULL) { 00268 m_csa = csa; 00269 } 00270 00272 bwt_of_csa_psi(const bwt_of_csa_psi& bwt_of_csa) { 00273 m_csa = bwt_of_csa.m_csa; 00274 } 00275 00277 00281 value_type operator[](size_type i)const { 00282 assert(m_csa != NULL); 00283 assert(i < size()); 00284 size_type pos = m_csa->psi(i); 00285 return algorithm::get_ith_character_of_the_first_row(pos, *m_csa); 00286 } 00287 00289 bwt_of_csa_psi& operator=(const bwt_of_csa_psi& bwt_of_csa) { 00290 if (this != &bwt_of_csa) { 00291 m_csa = bwt_of_csa.m_csa; 00292 } 00293 return *this; 00294 } 00295 00297 size_type size()const { 00298 return m_csa->size(); 00299 } 00300 00302 size_type empty()const { 00303 return m_csa->empty(); 00304 } 00305 00307 void swap(bwt_of_csa_psi& bwt_of_csa) { 00308 if (this != &bwt_of_csa) { 00309 ;// std::swap(m_csa, bwt_of_csa.m_csa); // do not exchange the supported structure! 00310 } 00311 } 00312 00314 00317 const_iterator begin()const { 00318 return const_iterator(this, 0); 00319 } 00320 00322 00325 const_iterator end()const { 00326 return const_iterator(this, size()); 00327 } 00328 }; 00329 00330 00331 00332 00333 } 00334 00335 #endif