b-tree-plus-alpha
Loading...
Searching...
No Matches
dynamic_wavelet_tree.hpp
1#pragma once
3
4namespace stool
5{
6 namespace bptree
7 {
14 {
16 std::vector<std::vector<BIT_SEQUENCE>> bits_seq;
17 std::vector<int64_t> char_rank_vec;
18 std::vector<uint8_t> alphabet;
19 uint64_t rank_bit_size = 0;
20
21 public:
25
26
30 {
31 this->alphabet.clear();
32 };
33
37 DynamicWaveletTree(const std::vector<uint8_t> &_alphabet)
38 {
39 this->set_alphabet(_alphabet);
40 };
45 {
46 this->initialize();
47 };
51 DynamicWaveletTree(DynamicWaveletTree &&) noexcept = default;
52
54
58
59
62 DynamicWaveletTree &operator=(const DynamicWaveletTree &) = delete;
66 DynamicWaveletTree &operator=(DynamicWaveletTree &&) noexcept = default;
70 uint8_t operator[](uint64_t i) const
71 {
72 return this->at(i);
73 }
74
76
80
81
84 uint64_t size() const
85 {
86 if (!this->has_empty_alphabet())
87 {
88 return this->bits_seq[0][0].size();
89 }
90 else
91 {
92 return 0;
93 }
94 }
95
99 uint64_t get_alphabet_size() const
100 {
101 return this->alphabet.size();
102 }
103
108 {
109 return this->rank_bit_size == 0;
110 }
111
116 {
117 assert(this->alphabet.size() > 0);
118 return this->alphabet[0];
119 }
123 int64_t get_lexicographic_order(uint8_t c) const
124 {
125 return this->char_rank_vec[c];
126 }
127
131 uint64_t height() const
132 {
133 return this->bits_seq.size();
134 }
139 uint64_t size_in_bytes(bool only_dynamic_memory = false) const
140 {
141 uint64_t total_size_in_bytes = 0;
142 for (uint64_t h = 0; h < this->bits_seq.size(); h++)
143 {
144 for (const BIT_SEQUENCE &seq : this->bits_seq[h])
145 {
146 total_size_in_bytes += seq.size_in_bytes(only_dynamic_memory);
147 }
148 }
149 return total_size_in_bytes;
150 }
151
153
157
158
163 uint64_t at(uint64_t i) const
164 {
165 assert(!this->has_empty_alphabet());
166 if (!this->has_empty_alphabet())
167 {
168 return this->alphabet[this->get_lexicographic_order_by_position(i)];
169 }
170 else
171 {
172 throw std::range_error("Error: DynamicSequence::at(i)");
173 }
174 }
179 int64_t one_based_rank(uint64_t i, uint64_t c) const
180 {
181 if (!this->has_empty_alphabet())
182 {
183 assert(c < char_rank_vec.size());
184 int64_t c_rank = this->char_rank_vec[c];
185 assert(c_rank <= (int64_t)this->alphabet.size());
186
187 if (c_rank == -1 || i == 0)
188 {
189 return 0;
190 }
191 else
192 {
193 return this->rank_sub(i - 1, c_rank);
194 }
195 }
196 else
197 {
198 return 0;
199 }
200 }
205 int64_t select(uint64_t i, uint64_t c) const
206 {
207 if (!this->has_empty_alphabet())
208 {
209 assert(c < char_rank_vec.size());
210 int64_t c_rank = this->char_rank_vec[c];
211 assert(c_rank <= (int64_t)this->alphabet.size());
212
213 if (c_rank == -1)
214 {
215 return -1;
216 }
217 else
218 {
219 return this->select_sub(i + 1, c_rank);
220 }
221 }
222 else
223 {
224 return -1;
225 }
226 }
227
232 uint64_t get_lexicographic_order_by_position(uint64_t i) const
233 {
234 assert(!this->has_empty_alphabet());
235 if (!this->has_empty_alphabet())
236 {
237 if (i < this->size())
238 {
239 uint64_t next_nth = i;
240 uint64_t j = 0;
241 for (int64_t h = 0; h < (int64_t)this->height(); h++)
242 {
243 bool b = this->bits_seq[h][j].at(next_nth);
244 next_nth = this->bits_seq[h][j].one_based_rank(next_nth, b);
245 j = (j * 2) + (b ? 1 : 0);
246 }
247 return j;
248 }
249 else
250 {
251 throw std::range_error("Error: DynamicSequence::get_nth_char_rank(nth)");
252 }
253 }
254 else
255 {
256 throw std::range_error("Error: DynamicSequence::get_nth_char_rank(nth)");
257 }
258 }
259
264 uint64_t count_c(uint8_t c) const
265 {
266 int64_t c_rank = this->get_lexicographic_order(c);
267 if (c_rank == -1)
268 {
269 return 0;
270 }
271 else
272 {
273 uint64_t idx = (c_rank / 2);
274 uint64_t bit_idx = 0;
275 bool b = stool::LSBByte::get_bit(c_rank, bit_idx);
276 return this->bits_seq[this->bits_seq.size() - 1][idx].count_c(b);
277 }
278 }
279
281
285
286
290 std::string to_string() const
291 {
292 std::string s;
293 s.resize(this->size());
294 for (uint64_t i = 0; i < this->size(); i++)
295 {
296 s[i] = this->at(i);
297 }
298 return s;
299 }
300
304 std::vector<uint8_t> to_u8_vector() const
305 {
306 std::vector<uint8_t> s;
307 s.resize(this->size());
308 for (uint64_t i = 0; i < this->size(); i++)
309 {
310 s[i] = this->at(i);
311 }
312 return s;
313 }
314
318 std::vector<uint8_t> to_alphabet_vector() const
319 {
320 std::vector<uint8_t> r = this->alphabet;
321 return r;
322 }
323
325
329
330
335 {
336 this->bits_seq.swap(item.bits_seq);
337
338 this->char_rank_vec.swap(item.char_rank_vec);
339 this->alphabet.swap(item.alphabet);
340 std::swap(this->rank_bit_size, item.rank_bit_size);
341 }
342
346 void set_alphabet(const std::vector<uint8_t> &_alphabet)
347 {
348 this->initialize();
349
350 for (auto c : _alphabet)
351 {
352 this->alphabet.push_back(c);
353 }
354 std::sort(this->alphabet.begin(), this->alphabet.end());
355
356 this->char_rank_vec.resize(256, -1);
357 for (uint64_t i = 0; i < alphabet.size(); i++)
358 {
359 this->char_rank_vec[alphabet[i]] = i;
360 }
361 this->rank_bit_size = stool::LSBByte::get_code_length(alphabet.size() - 1);
362
363 for (uint64_t i = 0; i < rank_bit_size; i++)
364 {
365 this->bits_seq.push_back(std::vector<BIT_SEQUENCE>());
366 if (i == 0)
367 {
368 this->bits_seq[i].push_back(BIT_SEQUENCE());
369 }
370 else
371 {
372 uint64_t x = 1ULL << i;
373 for (uint64_t j = 0; j < x; j++)
374 {
375 this->bits_seq[i].push_back(BIT_SEQUENCE());
376 }
377 }
378 }
379 }
380
384 void clear()
385 {
386 for (uint64_t i = 0; i < this->bits_seq.size(); i++)
387 {
388 for (uint64_t j = 0; j < this->bits_seq[i].size(); j++)
389 {
390 this->bits_seq[i][j].clear();
391 }
392 }
393 }
398 void push_back(uint8_t c)
399 {
400 assert(!this->has_empty_alphabet());
401 if (!this->has_empty_alphabet())
402 {
403 int64_t c_rank = this->char_rank_vec[c];
404 if (c_rank == -1)
405 {
406 assert(false);
407 throw std::runtime_error("Error: DynamicSequence::push_back()");
408 }
409 else
410 {
411 this->push_back_sub(c_rank);
412 }
413 }
414 else
415 {
416 throw std::runtime_error("Error: DynamicSequence::push_back()");
417 }
418 }
423 void push_many(const std::vector<uint8_t> &str)
424 {
425 for (auto c : str)
426 {
427 this->push_back(c);
428 }
429 }
430
435 void insert(uint64_t i, uint8_t c)
436 {
437 assert(!this->has_empty_alphabet());
438 if (!this->has_empty_alphabet())
439 {
440 int64_t c_rank = this->char_rank_vec[c];
441 if (c_rank == -1)
442 {
443 assert(false);
444 throw std::runtime_error("Error: DynamicSequence::insert(i, c)");
445 }
446 else
447 {
448 this->insert_sub(i, c_rank);
449 }
450 }
451 else
452 {
453 throw std::runtime_error("Error: DynamicSequence::insert(i, c)");
454 }
455 }
460 void remove(uint64_t i)
461 {
462 if (i < this->size())
463 {
464 uint64_t next_nth = i;
465 uint64_t j = 0;
466 for (int64_t h = 0; h < (int64_t)this->height(); h++)
467 {
468 uint64_t current_nth = next_nth;
469 bool b = this->bits_seq[h][j].at(current_nth);
470 next_nth = this->bits_seq[h][j].one_based_rank(current_nth, b);
471 this->bits_seq[h][j].remove(current_nth);
472 j = (j * 2) + (b ? 1 : 0);
473 }
474 }
475 else
476 {
477 throw std::range_error("Error: DynamicSequence::remove(nth)");
478 }
479 }
480
482
486
487
492 std::vector<std::string> get_memory_usage_info(int message_paragraph = stool::Message::SHOW_MESSAGE) const
493 {
494 std::vector<std::string> r;
495 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "=DynamicWaveletTree: " + std::to_string(this->size_in_bytes()) + " bytes =");
496 uint64_t counter = 0;
497 for (uint64_t h = 0; h < this->bits_seq.size(); h++)
498 {
499 for (const BIT_SEQUENCE &seq : this->bits_seq[h])
500 {
501 if (counter < 5)
502 {
503 std::vector<std::string> log1 = seq.get_memory_usage_info(message_paragraph + 1);
504 for (auto s : log1)
505 {
506 r.push_back(s);
507 }
508 }
509 counter++;
510 }
511 }
512 if (counter > 5)
513 {
514 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "Omitted details of " + std::to_string(counter - 5) + " dynamic bit sequences.");
515 }
516
517 r.push_back(stool::Message::get_paragraph_string(message_paragraph) + "==");
518 return r;
519 }
524 void print_statistics(int message_paragraph = stool::Message::SHOW_MESSAGE) const
525 {
526 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Statistics(DynamicWaveletTree):" << std::endl;
527 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "Alphabet size: " << this->alphabet.size() << std::endl;
528 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "Text length: " << this->size() << std::endl;
529 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "Estimated memory usage: " << this->size_in_bytes() << " bytes" << std::endl;
530 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
531 }
536 void print_memory_usage(int message_paragraph = stool::Message::SHOW_MESSAGE) const
537 {
538 std::vector<std::string> log = this->get_memory_usage_info(message_paragraph);
539 for (std::string &s : log)
540 {
541 std::cout << s << std::endl;
542 }
543 }
548 void print_content(int message_paragraph = stool::Message::SHOW_MESSAGE) const
549 {
550 std::string s = this->to_string();
551 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "Content(DynamicWaveletTree):" << std::endl;
552 std::cout << stool::Message::get_paragraph_string(message_paragraph + 1) << "String: " << s << "(" << s.size() << ")" << std::endl;
553 std::cout << stool::Message::get_paragraph_string(message_paragraph) << "[END]" << std::endl;
554 }
555
559 void print_info() const
560 {
561 std::cout << "================DynamicSequence==================" << std::endl;
562 stool::DebugPrinter::print_characters(this->alphabet, "Alphabet");
563 stool::DebugPrinter::print_integers(this->char_rank_vec, "Char_rank_vec");
564 std::cout << "Rank_bit_size: " << this->rank_bit_size << std::endl;
565
566 for (uint64_t i = 0; i < this->rank_bit_size; i++)
567 {
568 std::cout << "level: " << i << " / count: " << this->bits_seq[i].size() << std::endl;
569 for (uint64_t j = 0; j < this->bits_seq[i].size(); j++)
570 {
571 std::cout << this->bits_seq[i][j].to_string() << std::endl;
572 }
573 }
574 std::cout << "==================================" << std::endl;
575 }
577
581
582
585 static DynamicWaveletTree build(const std::vector<uint8_t> &_text, const std::vector<uint8_t> &_alphabet)
586 {
587 DynamicWaveletTree dwt(_alphabet);
588 dwt.build_bits(_text, 0, 0);
589 return dwt;
590 }
591
595 static DynamicWaveletTree load_from_file(std::ifstream &ifs)
596 {
598 uint64_t _alphabet_size = 0;
599 ifs.read(reinterpret_cast<char *>(&_alphabet_size), sizeof(uint64_t));
600
601 std::vector<uint8_t> _alphabet;
602 _alphabet.resize(_alphabet_size);
603 ifs.read(reinterpret_cast<char *>(_alphabet.data()), _alphabet_size * sizeof(uint8_t));
604
605 r.set_alphabet(_alphabet);
606 for (auto &it : r.bits_seq)
607 {
608 for (auto &it2 : it)
609 {
610 auto bits = BIT_SEQUENCE::load_from_file(ifs);
611 it2.swap(bits);
612 }
613 }
614 return r;
615 }
619 static void store_to_file(DynamicWaveletTree &item, std::ofstream &os)
620 {
621 uint64_t alphabet_size = item.alphabet.size();
622 os.write(reinterpret_cast<const char *>(&alphabet_size), sizeof(uint64_t));
623 os.write(reinterpret_cast<const char *>(item.alphabet.data()), alphabet_size * sizeof(uint8_t));
624 for (auto &it : item.bits_seq)
625 {
626 for (auto &it2 : it)
627 {
629 }
630 }
631 }
633
634 private:
635 void build_bits(const std::vector<uint8_t> &_text, uint64_t h, uint64_t i)
636 {
637 uint64_t bit_idx = this->rank_bit_size - h - 1;
638 std::vector<bool> bits;
639 bits.resize(_text.size(), false);
640 uint64_t counter = 0;
641 uint64_t bits1_count = 0;
642 uint64_t bits0_count = 0;
643
644 for (uint8_t c : _text)
645 {
646 int64_t c_rank = this->char_rank_vec[c];
647 bool b = stool::LSBByte::get_bit(c_rank, bit_idx);
648 bits[counter++] = b;
649 if (b)
650 {
651 bits1_count++;
652 }
653 else
654 {
655 bits0_count++;
656 }
657 }
658 BIT_SEQUENCE dbs = BIT_SEQUENCE::build(bits);
659 this->bits_seq[h][i].swap(dbs);
660 if (h + 1 < rank_bit_size)
661 {
662 uint64_t next_i = i * 2;
663 {
664 std::vector<uint8_t> left;
665 left.resize(bits0_count);
666 counter = 0;
667
668 for (uint8_t c : _text)
669 {
670 int64_t c_rank = this->char_rank_vec[c];
671 bool b = stool::LSBByte::get_bit(c_rank, bit_idx);
672 if (!b)
673 {
674 left[counter++] = c;
675 }
676 }
677 this->build_bits(left, h + 1, next_i);
678 }
679 {
680 std::vector<uint8_t> right;
681 right.resize(bits1_count);
682 counter = 0;
683
684 for (uint8_t c : _text)
685 {
686 int64_t c_rank = this->char_rank_vec[c];
687 bool b = stool::LSBByte::get_bit(c_rank, bit_idx);
688 if (b)
689 {
690 right[counter++] = c;
691 }
692 }
693 this->build_bits(right, h + 1, next_i + 1);
694 }
695 }
696 }
697
698 private:
699 void initialize()
700 {
701 for (uint64_t i = 0; i < this->bits_seq.size(); i++)
702 {
703 for (uint64_t j = 0; j < this->bits_seq[i].size(); j++)
704 {
705 this->bits_seq[i][j].clear();
706 // delete this->bits_seq[i][j];
707 }
708 }
709 this->bits_seq.clear();
710 this->char_rank_vec.clear();
711 this->alphabet.clear();
712 }
713
714 private:
715 void push_back_sub(uint64_t c_rank)
716 {
717#ifdef DEBUG
718 uint64_t _size = this->size();
719#endif
720 uint64_t pos = 0;
721 for (uint64_t i = 0; i < this->rank_bit_size; i++)
722 {
723 bool b = stool::LSBByte::get_bit(c_rank, this->rank_bit_size - 1 - i);
724 this->bits_seq[i][pos].push_back(b ? 1 : 0);
725 pos = (pos * 2) + (b ? 1 : 0);
726 }
727
728#ifdef DEBUG
729 assert(this->size() == _size + 1);
730#endif
731 }
732 int64_t rank_sub(uint64_t i, uint64_t c_rank) const
733 {
734 bool b1 = stool::LSBByte::get_bit(c_rank, this->rank_bit_size - 1);
735 uint64_t _rank = this->bits_seq[0][0].one_based_rank(i + 1, b1);
736 if (_rank == 0)
737 {
738 return 0;
739 }
740 else
741 {
742 uint64_t nth = _rank - 1;
743 uint64_t next = b1 ? 1 : 0;
744
745 for (uint64_t i = 1; i < this->rank_bit_size; i++)
746 {
747 bool bx = stool::LSBByte::get_bit(c_rank, this->rank_bit_size - 1 - i);
748
749 if (nth >= this->bits_seq[i][next].size())
750 {
751 assert(false);
752 throw std::range_error("Error: DynamicSequence::rank_sub()");
753 }
754
755 uint64_t _rankx = this->bits_seq[i][next].one_based_rank(nth + 1, bx);
756 if (_rankx == 0)
757 {
758 return 0;
759 }
760 else
761 {
762 nth = _rankx - 1;
763 next = (next * 2) + (bx ? 1 : 0);
764 }
765 }
766 return nth + 1;
767 }
768 }
769 int64_t select_sub(uint64_t nth, uint64_t c_rank) const
770 {
771 int64_t depth = this->bits_seq.size();
772 assert(depth > 0);
773 int64_t h = 0;
774 int64_t j = c_rank / 2;
775 bool hbit = stool::LSBByte::get_bit(c_rank, h);
776 assert(j < (int64_t)this->bits_seq[depth - h - 1].size());
777 uint64_t hbit_rank = this->bits_seq[depth - h - 1][j].count_c(hbit);
778
779 if (nth <= hbit_rank)
780 {
781 int64_t hbit_select = this->bits_seq[depth - h - 1][j].select(nth - 1, hbit);
782
783 assert(hbit_select >= 0);
784
785 int64_t next_nth = hbit_select + 1;
786 j = j / 2;
787 h++;
788 while (h < (int64_t)this->rank_bit_size)
789 {
790 hbit = stool::LSBByte::get_bit(c_rank, h);
791 assert(next_nth <= this->bits_seq[depth - h - 1][j].count_c(hbit));
792 hbit_select = this->bits_seq[depth - h - 1][j].select(next_nth - 1, hbit);
793
794 assert(hbit_select >= 0);
795 next_nth = hbit_select + 1;
796 j = j / 2;
797 h++;
798 }
799 assert(next_nth > 0);
800 return next_nth - 1;
801 }
802 else
803 {
804 return -1;
805 }
806 }
807 void insert_sub(uint64_t nth, uint8_t c_rank)
808 {
809 if (nth <= this->size())
810 {
811
812 uint64_t next_nth = nth;
813 uint64_t j = 0;
814 for (int64_t h = 0; h < (int64_t)this->height(); h++)
815 {
816 bool hbit = stool::LSBByte::get_bit(c_rank, this->rank_bit_size - h - 1);
817 assert(next_nth <= this->bits_seq[h][j].size());
818 this->bits_seq[h][j].insert(next_nth, hbit);
819 next_nth = this->bits_seq[h][j].one_based_rank(next_nth, hbit);
820 j = (j * 2) + (hbit ? 1 : 0);
821 }
822 }
823 else
824 {
825 throw std::range_error("Error: DynamicSequence::insert(nth, c_rank)");
826 }
827 }
828 void build_from_text(const std::vector<uint8_t> &_text, const std::vector<uint8_t> &_alphabet)
829 {
830 DynamicWaveletTree dwt = DynamicWaveletTree::build(_text, _alphabet);
831 this->swap(dwt);
832 }
833 };
834
835 // template <typename T>
836 // using VLCDequeSeq = DynamicSequence<VLCDeque, T>;
837 }
838
839}
A dynamic data structure supporting rank and select queries on a bit sequence B[0....
Definition dynamic_bit_sequence.hpp:24
static void store_to_file(DynamicBitSequence &item, std::ofstream &os)
Save the given instance item to a file stream os.
Definition dynamic_bit_sequence.hpp:681
static DynamicBitSequence build(const std::vector< bool > &items)
Build a new DynamicBitSequence from a given sequence items.
Definition dynamic_bit_sequence.hpp:639
static DynamicBitSequence load_from_file(std::ifstream &ifs)
Returns the DynamicBitSequence instance loaded from a file stream ifs.
Definition dynamic_bit_sequence.hpp:661
A dynamic data structure supporting rank and select queries on a string T[0..n-1] over alphabet U[0....
Definition dynamic_wavelet_tree.hpp:14
DynamicWaveletTree(DynamicWaveletTree &&) noexcept=default
Default move constructor.
std::vector< std::string > get_memory_usage_info(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Return the memory usage information of this data structure as a vector of strings.
Definition dynamic_wavelet_tree.hpp:492
bool has_empty_alphabet() const
Check if the alphabet U is empty.
Definition dynamic_wavelet_tree.hpp:107
void push_many(const std::vector< uint8_t > &str)
Add a given sequence Q[0..k-1] to the end of T[0..n-1] (i.e., T = T[0..n-1]Q[0..k-1])
Definition dynamic_wavelet_tree.hpp:423
void swap(DynamicWaveletTree &item)
Swap operation.
Definition dynamic_wavelet_tree.hpp:334
void set_alphabet(const std::vector< uint8_t > &_alphabet)
Initialize this instance with |T| = 0 and U = _alphabet.
Definition dynamic_wavelet_tree.hpp:346
void print_info() const
Print the statistics of this data structure.
Definition dynamic_wavelet_tree.hpp:559
void print_content(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the string T.
Definition dynamic_wavelet_tree.hpp:548
static void store_to_file(DynamicWaveletTree &item, std::ofstream &os)
Save the given instance item to a file stream os.
Definition dynamic_wavelet_tree.hpp:619
uint64_t at(uint64_t i) const
Return T[i].
Definition dynamic_wavelet_tree.hpp:163
std::vector< uint8_t > to_alphabet_vector() const
Return the alphabet U.
Definition dynamic_wavelet_tree.hpp:318
int64_t one_based_rank(uint64_t i, uint64_t c) const
Counts the number of occurrences of a character c in T[0..i-1].
Definition dynamic_wavelet_tree.hpp:179
void remove(uint64_t i)
Remove the character at the position i from T.
Definition dynamic_wavelet_tree.hpp:460
int64_t get_lexicographic_order(uint8_t c) const
Return the lexicographic order of a given character c in the alphabet U if it exists,...
Definition dynamic_wavelet_tree.hpp:123
static DynamicWaveletTree build(const std::vector< uint8_t > &_text, const std::vector< uint8_t > &_alphabet)
Build a new DynamicWaveletTree from a given sequence _text and alphabet _alphabet.
Definition dynamic_wavelet_tree.hpp:585
void push_back(uint8_t c)
Adds a character c to the end of T.
Definition dynamic_wavelet_tree.hpp:398
uint64_t get_smallest_character_in_alphabet() const
Return the smallest character in the alphabet U.
Definition dynamic_wavelet_tree.hpp:115
void print_statistics(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the statistics of this data structure.
Definition dynamic_wavelet_tree.hpp:524
static DynamicWaveletTree load_from_file(std::ifstream &ifs)
Returns the DynamicWaveletTree instance loaded from a file stream ifs.
Definition dynamic_wavelet_tree.hpp:595
void print_memory_usage(int message_paragraph=stool::Message::SHOW_MESSAGE) const
Print the memory usage information of this data structure.
Definition dynamic_wavelet_tree.hpp:536
void insert(uint64_t i, uint8_t c)
Insert a character c into T as T[i].
Definition dynamic_wavelet_tree.hpp:435
DynamicWaveletTree()
Default constructor with |T| = 0 and |U| = 0.
Definition dynamic_wavelet_tree.hpp:29
void clear()
Clear the elements in T.
Definition dynamic_wavelet_tree.hpp:384
uint64_t get_alphabet_size() const
Return alphabet size |U|.
Definition dynamic_wavelet_tree.hpp:99
uint64_t size() const
Return |T|.
Definition dynamic_wavelet_tree.hpp:84
std::string to_string() const
Return T as a string.
Definition dynamic_wavelet_tree.hpp:290
uint64_t height() const
Return the height of the wavelet tree.
Definition dynamic_wavelet_tree.hpp:131
uint64_t size_in_bytes(bool only_dynamic_memory=false) const
Returns the total memory usage in bytes.
Definition dynamic_wavelet_tree.hpp:139
std::vector< uint8_t > to_u8_vector() const
Return T as a vector of uint8_t.
Definition dynamic_wavelet_tree.hpp:304
uint64_t get_lexicographic_order_by_position(uint64_t i) const
Return the lexicographic order of T[i] in the alphabet U.
Definition dynamic_wavelet_tree.hpp:232
DynamicWaveletTree(const std::vector< uint8_t > &_alphabet)
Default constructor with |T| = 0 and U = _alphabet.
Definition dynamic_wavelet_tree.hpp:37
int64_t select(uint64_t i, uint64_t c) const
Returns the position p of the (i+1)-th 1 in B if such a position exists, otherwise returns -1.
Definition dynamic_wavelet_tree.hpp:205
~DynamicWaveletTree()
Destroy the Dynamic Wavelet Tree object.
Definition dynamic_wavelet_tree.hpp:44
uint64_t count_c(uint8_t c) const
Return the number of occurrences of the character c in T.
Definition dynamic_wavelet_tree.hpp:264
A dynamic data structure supporting rank and select queries on a bit sequence.