SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/suffixarray_helper.hpp
Go to the documentation of this file.
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