Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
trie.hpp
Go to the documentation of this file.
1
6/*
7 * This file is part of Algorithms library toolkit.
8 * Copyright (C) 2017 Jan Travnicek (jan.travnicek@fit.cvut.cz)
9
10 * Algorithms library toolkit is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14
15 * Algorithms library toolkit is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19
20 * You should have received a copy of the GNU General Public License
21 * along with Algorithms library toolkit. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#pragma once
25
26#include <memory>
27#include <iterator>
28#include <string>
29#include <compare>
30#include <tuple>
31
32#include <ext/pair>
33#include <ext/map>
34#include <ext/ostream>
35
36namespace ext {
37
46template < class Key, class Value >
47class trie {
52 Value m_data;
53
58 trie * m_parent;
59
66 ext::map < Key, trie > m_children;
67
68public:
76 return m_parent;
77 }
78
85 const trie * getParent ( ) const {
86 return m_parent;
87 }
88
95 Value & getData ( ) {
96 return m_data;
97 }
98
105 const Value & getData ( ) const {
106 return m_data;
107 }
108
116 return m_children;
117 }
118
126 return m_children;
127 }
128
134
140
141// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
142
153 ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( getChildren ( ) );
154
155 typename ext::map < Key, trie >::iterator iter = children.insert ( std::move ( key ), std::move ( value ) ).first;
156 iter->second.m_parent = this;
157 return iter;
158 }
159
170 return insert ( std::move ( key ), trie < Key, Value > ( value ) );
171 }
172
181 ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( getChildren ( ) );
182
183 for ( ; begin != end; ++begin )
184 children.insert ( * begin ).first->second.m_parent = this;
185 }
186
187// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
188
196 trie ( Value && data, ext::map < Key, trie > && children ) : m_data ( std::move ( data ) ), m_parent ( nullptr ), m_children ( std::move ( children ) ) {
197 for ( std::pair < const Key, trie > & child : m_children )
198 child.second.m_parent = this;
199 }
200
208 trie ( const Value & data, const ext::map < Key, trie > & subtries ) : trie ( Value ( data ), ext::map < Key, trie > ( subtries ) ) {
209 }
210
220 template < typename ... Types >
221 trie ( const Value & data, Types ... subtries ) : trie ( data, ext::map < Key, trie > { subtries ... } ) {
222 }
223
233 template < typename ... Types >
234 trie ( Value && data, Types ... subtries ) : trie ( std::move ( data ), ext::map < Key, trie > { subtries ... } ) {
235 }
236
245 trie ( const Value & data, const_children_iterator begin, const_children_iterator end ) : trie ( data, ext::map < Key, trie > ( begin, end ) ) {
246 }
247
252 ~trie ( ) noexcept = default;
253
260 trie ( const trie & other ) : m_data ( other.m_data ), m_parent ( other.m_parent ), m_children ( other.m_children ) {
261 for ( std::pair < const Key, trie > & child : m_children )
262 child.second.m_parent = this;
263 }
264
271 trie ( trie && other ) noexcept : m_data ( std::move ( other.m_data ) ), m_parent ( other.m_parent ), m_children ( std::move ( other.m_children ) ) {
272 for ( std::pair < const Key, trie > & child : m_children )
273 child.second.m_parent = this;
274 }
275
284 trie & operator =( const trie & node ) {
285 * this = trie ( node );
286 return * this;
287 }
288
297 trie & operator =( trie && node ) noexcept {
298 m_data = std::move ( node.m_data );
299 m_children = std::move ( node.m_children );
300
301 for ( std::pair < const Key, trie > & child : m_children )
302 child.second.m_parent = this;
303
304 return * this;
305 }
306
307// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
308
316 return m_children.begin ( );
317 }
318
326 return m_children.begin ( );
327 }
328
336 return m_children.end ( );
337 }
338
346 return m_children.end ( );
347 }
348
349// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
350
358 ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( getChildren ( ) );
359
360 return children.erase ( position );
361 }
362
363// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
364
375 template < class ... Indexes >
376 const Value & operator ()( Indexes ... indexes ) const {
377 return this->operator ()( { static_cast < Key > ( indexes ) ... } );
378 }
379
388 const Value & operator ()( std::initializer_list < Key > indexes ) const {
389 const trie * node = this;
390
391 for ( Key index : indexes ) {
392 node = & node->getChildren ( ).find ( index )->second;
393 }
394
395 return node->getData ( );
396 }
397
408 template < class ... Indexes >
409 Value & operator ()( Indexes ... indexes ) {
410 return this->operator ()( { static_cast < Key > ( indexes ) ... } );
411 }
412
421 Value & operator ()( std::initializer_list < Key > indexes ) {
422 trie * node = this;
423
424 for ( Key index : indexes ) {
425 node = & node->getChildren ( ).find ( index )->second;
426 }
427
428 return node->getData ( );
429 }
430
431// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
432
441 bool checkStructure ( const trie & node ) const {
442 bool sign = true;
443
444 for ( const std::pair < const Key, trie > & child : node.getChildren ( ) )
445 sign &= child.second.getParent ( ) == & node && checkStructure ( child.second );
446
447 return sign;
448 }
449
458 bool checkStructure ( ) const {
459 return m_parent == nullptr && checkStructure ( * this );
460 }
461
462// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
463
471 friend void swap ( trie & first, trie & second ) {
472 swap ( first.m_data, second.m_data );
473 swap ( first.m_children, second.m_children );
474 for ( trie & child : first.m_children )
475 child.m_parent = & first;
476 for ( trie & child : second.m_children )
477 child.m_parent = & second;
478 }
479
480// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
481
490 bool operator ==( const trie & other ) const {
491 return std::tie ( this->getData ( ), this->getChildren ( ) ) == std::tie ( other.getData ( ), other.getChildren ( ) );
492 }
493
502 auto operator <=> ( const trie & other ) const -> std::common_comparison_category_t < decltype ( std::declval < Key > ( ) <=> std::declval < Key > ( ) ), decltype ( std::declval < Value > ( ) <=> std::declval < Value > ( ) ) > {
503 return std::tie ( this->getData ( ), this->getChildren ( ) ) <=> std::tie ( other.getData ( ), other.getChildren ( ) );
504 }
505
506// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
507
531 os << "\\-";
532 std::string prefix ( " " );
533
534 os << getData ( ) << std::endl;
535
536 size_t i = 0;
537 for ( const std::pair < const Key, trie < Key, Value > > & subdata : getChildren ( ) ) {
538 os << prefix << "|" << std::endl;
539 nicePrint ( os, subdata, prefix, i == m_children.size ( ) - 1 );
540 ++i;
541 }
542 return os;
543 }
544
545private:
568 static void nicePrint ( ext::ostream & os, const std::pair < const Key, trie < Key, Value > > & data, std::string prefix, const bool last ) {
569 os << prefix;
570
571 if ( last ) {
572 os << "\\-";
573 prefix += " ";
574 } else {
575 os << "|-";
576 prefix += "| ";
577 }
578
579 os << data.first << ":" << data.second.getData ( ) << std::endl;
580
581 size_t i = 0;
582 for ( const std::pair < const Key, trie < Key, Value > > & subdata : data.second ) {
583 os << prefix << "|" << std::endl;
584 nicePrint ( os, subdata, prefix, i == data.second.m_children.size ( ) - 1 );
585 ++i;
586 }
587 }
588
589};
590
602template < class Key, class Value >
604 out << "[";
605
606 out << t.getData ( ) << ";";
607
608 for ( typename ext::map < Key, trie < Key, Value > >::const_iterator iter = t.getChildren ( ).begin ( ); iter != t.getChildren ( ).end ( ); ++ iter) {
609 if ( iter != t.getChildren ( ).begin ( ) ) {
610 out << ",";
611 }
612
613 out << iter->first << ":" << iter->second;
614 }
615
616 out << "]";
617 return out;
618}
619
620} /* namespace ext */
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: map.hpp:185
std::pair< iterator, bool > insert(const T &key, const R &value)
Insert variant with explicit key and value parameters.
Definition: map.hpp:118
auto end() &
Inherited behavior of end for non-const instance.
Definition: map.hpp:215
typename std::map< T, R, Cmp, Alloc >::iterator iterator
The iterator type is inheried.
Definition: map.hpp:101
size_t erase(const K &key)
Erase by key of arbitrary type.
Definition: map.hpp:340
Definition: ostream.h:14
Class introducing a trie with interface trying to be close to the interface of standard library conta...
Definition: trie.hpp:47
const_children_iterator begin() const
Getter of a children iterator to the begining of children.
Definition: trie.hpp:315
ext::map< Key, trie >::const_iterator const_children_iterator
The iterator type over children of the node.
Definition: trie.hpp:139
trie(trie &&other) noexcept
Move constructor of the trie.
Definition: trie.hpp:271
friend void swap(trie &first, trie &second)
Swap method of two tries.
Definition: trie.hpp:471
children_iterator erase(const_children_iterator position)
Erases a subtrie from a trie on given by position.
Definition: trie.hpp:357
trie(const Value &data, const_children_iterator begin, const_children_iterator end)
Constructor of the trie from value to be stored in the root node and range of key-value pairs to cons...
Definition: trie.hpp:245
const ext::map< Key, trie > & getChildren() const
Getter of children of the root node.
Definition: trie.hpp:125
trie(Value &&data, ext::map< Key, trie > &&children)
Constructor of the trie from value to be stored in the root node and children tries.
Definition: trie.hpp:196
const trie * getParent() const
Getter of the parent node. Null if the node is root.
Definition: trie.hpp:85
~trie() noexcept=default
Dectructor of the trie.
ext::ostream & nicePrint(ext::ostream &os) const
Internal method of printing a trie into a stream.
Definition: trie.hpp:530
auto operator<=>(const trie &other) const -> std::common_comparison_category_t< decltype(std::declval< Key >()<=> std::declval< Key >()), decltype(std::declval< Value >()<=> std::declval< Value >()) >
Less comparison operator.
Definition: trie.hpp:502
trie(const Value &data, Types ... subtries)
Constructor of the trie from value to be stored in the root node and pack of children tries.
Definition: trie.hpp:221
children_iterator end()
Getter of a children iterator one after the last child.
Definition: trie.hpp:345
void insert(const_children_iterator begin, const_children_iterator end)
Inserts subtries given by range of key-value pairs at specified position.
Definition: trie.hpp:180
ext::map< Key, trie > & getChildren()
Getter of children of the root node.
Definition: trie.hpp:115
const_children_iterator insert(Key key, const trie< Key, Value > &value)
Inserts a subtrie into a trie.
Definition: trie.hpp:169
trie * getParent()
Getter of the parent node. Null if the node is root.
Definition: trie.hpp:75
bool operator==(const trie &other) const
Equality comparison operator.
Definition: trie.hpp:490
const Value & getData() const
Getter of the value in the root node.
Definition: trie.hpp:105
const Value & operator()(Indexes ... indexes) const
Access value given indexes to chindren allong the selection path.
Definition: trie.hpp:376
Value & getData()
Getter of the value in the root node.
Definition: trie.hpp:95
bool checkStructure() const
Helper method to traverse the trie and check all parent references are set correctly....
Definition: trie.hpp:458
trie(const Value &data, const ext::map< Key, trie > &subtries)
Constructor of the trie from value to be stored in the root node and children tries.
Definition: trie.hpp:208
const_children_iterator insert(Key key, trie< Key, Value > &&value)
Inserts a subtrie into a trie.
Definition: trie.hpp:152
trie(Value &&data, Types ... subtries)
Constructor of the trie from value to be stored in the root node and pack of children tries.
Definition: trie.hpp:234
bool checkStructure(const trie &node) const
Helper method to traverse the trie and check all parent references are set correctly.
Definition: trie.hpp:441
const_children_iterator end() const
Getter of a children iterator one after the last child.
Definition: trie.hpp:335
children_iterator begin()
Getter of a children iterator to the begining of children.
Definition: trie.hpp:325
trie & operator=(const trie &node)
Copy operator of assignment of the trie.
Definition: trie.hpp:284
ext::map< Key, trie >::iterator children_iterator
The iterator type over children of the node.
Definition: trie.hpp:133
p second
Definition: ToRegExpAlgebraic.h:126
int i
Definition: AllEpsilonClosure.h:118
Definition: sigHandler.cpp:20
constexpr tuple< Elements &... > tie(Elements &... args) noexcept
Helper of extended tuple of references construction. The tuple is constructed to reffer to values in ...
Definition: tuple.hpp:218
std::ostream & operator<<(ext::reference_wrapper< std::ostream > &os, std::ostream &(*const func)(std::ostream &))
Overloaded function allowing same operations on wrapped output stream as on the actual output stream,...
Definition: GlobalData.cpp:33
Definition: CompressedBitParallelTreeIndex.h:40
Definition: Node.cpp:11
Definition: FordFulkerson.hpp:16