Skip to content
Snippets Groups Projects
Commit 603c2c4a authored by Jan Trávníček's avatar Jan Trávníček
Browse files

tune tree structures

parent 8fff2988
No related branches found
No related tags found
No related merge requests found
......@@ -43,40 +43,27 @@ public:
return m_children;
}
 
void nicePrint ( std::ostream & os, std::string prefix, const bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << getData ( ) << std::endl;
for ( unsigned int i = 0; i < m_children.size ( ); ++i ) {
os << prefix << "|" << std::endl;
m_children[i].nicePrint ( os, prefix, i == m_children.size ( ) - 1 );
}
}
/**
* \brief
* The iterator type over children of the node
*/
typedef typename ext::vector < forward_tree >::const_iterator const_children_iterator;
 
class const_structure_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
typename ext::vector < forward_tree >::const_iterator node;
typename ext::deque < const forward_tree * > parents;
unsigned level;
 
bool virtual_node;
bool isEnd;
 
public:
const_structure_iterator ( typename ext::vector < forward_tree >::const_iterator n ) : node ( n ), parents ( ), level ( 0 ), virtual_node ( false ), isEnd ( false ) {
}
const_structure_iterator ( const const_structure_iterator & other ) : node ( other.node ), parents ( other.parents ), level ( other.level ), virtual_node ( other.virtual_node ) {
/**
* \brief
* Constructor of the iterator based on the iterator to child list
*
* \param n the iterator to child list
*/
const_structure_iterator ( typename ext::vector < forward_tree >::const_iterator n ) : node ( n ), parents ( ), virtual_node ( false ), isEnd ( false ) {
}
 
const_structure_iterator & operator ++( ) {
......@@ -88,7 +75,6 @@ public:
 
if ( node == parent->getChildren ( ).end ( ) ) {
parents.pop_back();
--level;
node = typename ext::vector < forward_tree >::const_iterator ( parent );
} else {
virtual_node = false;
......@@ -102,8 +88,6 @@ public:
typename ext::vector < forward_tree >::const_iterator newIter = node->getChildren ( ).begin ( );
 
if ( newIter != node->getChildren ( ).end ( ) ) {
++level;
parents.push_back ( & * node );
node = newIter;
} else {
......@@ -130,8 +114,6 @@ public:
typename ext::vector < forward_tree >::const_iterator newIter = node->getChildren ( ).end ( );
 
if ( newIter != node->getChildren ( ).begin ( ) ) {
++level;
parents.push_back ( & * node );
node = newIter;
--node;
......@@ -144,7 +126,6 @@ public:
 
if ( node == parent->getChildren ( ).begin ( ) ) {
parents.pop_back();
--level;
node = typename ext::vector < forward_tree >::const_iterator ( parent );
} else {
--node;
......@@ -180,7 +161,7 @@ public:
}
 
unsigned getLevel ( ) const {
return level;
return parents.size ( );
}
 
bool getVirtual ( ) const {
......@@ -314,13 +295,17 @@ public:
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
private:
const_children_iterator insert_helper ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
forward_tree * under_node = const_cast < forward_tree * > ( & * under );
ext::vector < forward_tree > & children = const_cast < ext::vector < forward_tree > & > ( under_node->getChildren ( ) );
return children.insert ( position, begin, end );
}
/**
* \brief
* Forward tree vector construction helper. Trees are nullary nodes having value given by values in the range begin to end.
*
* \tparam Iterator the type of iterators forming the range
*
* \param begin the start of the range of values
* \param end the end of the range of values
*
* \return vector of unary nodes constructed from the begin and end range
*/
template < typename Iterator >
ext::vector < forward_tree > fromIterator ( Iterator begin, Iterator end ) {
ext::vector < forward_tree > res;
......@@ -342,20 +327,52 @@ public:
return insert ( under, position, forward_tree < T > ( value ) );
}
 
/**
* \brief
* Insert helper for insertion specified by position in children and inserted subtrees given by range of iterators.
*
* \param under the node under which to add subtrees
* \param position the specification of position in children of the node where to add subtrees
* \param begin the start of the range of subtrees
* \param end the end of the range of subtrees
*
* \return updated position iterator pointing to the first node inserted
*/
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
ext::vector < forward_tree > & children = const_cast < ext::vector < forward_tree > & > ( under->getChildren ( ) );
return children.insert ( position, begin, end );
}
/**
* \brief
* Inserts a subtrees into a forward_tree. The subtrees are nullary nodes having value given by values in the range begin to end.
*
* \tparam Iterator the type of iterators forming the range
*
* \param under the node under which to add the subtree
* \param position the specification of position in children of the node where to add subtrees
* \param begin the start of the range of values
* \param end the end of the range of values
*
* \return updated position iterator pointing to the first node inserted
*/
template < class Iterator >
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, Iterator begin, Iterator end ) {
ext::vector < forward_tree > children = fromIterator ( begin, end );
 
return insert_helper ( under, position, children.begin ( ), children.cend ( ) );
}
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
return insert_helper ( under, position, begin, end );
return insert ( under, position, children.cbegin ( ), children.cend ( ) );
}
 
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
public:
/**
* \brief
* Constructor of the forward_tree from value to be stored in the root node and children trees.
*
* \param data the value to be stored in the root
* \param children list of subtrees
*/
forward_tree ( T && data, ext::vector < forward_tree > && children ) : m_data ( std::move ( data ) ), m_children ( std::move ( children ) ) {
}
 
......@@ -377,26 +394,6 @@ public:
forward_tree ( const T & data, const_children_iterator begin, const_children_iterator end ) : forward_tree ( data, ext::vector < forward_tree > ( begin, end ) ) {
}
 
~forward_tree ( ) noexcept {
}
forward_tree ( const forward_tree & other ) : m_data ( other.m_data ), m_children ( other.m_children ) {
}
forward_tree ( forward_tree && other ) noexcept : m_data ( std::move ( other.m_data ) ), m_children ( std::move ( other.m_children ) ) {
}
forward_tree & operator =( const forward_tree & node ) {
return this->operator =( forward_tree ( node ) );
}
forward_tree & operator =( forward_tree && node ) noexcept {
m_data = std::move ( node.m_data );
m_children = std::move ( node.m_children );
return * this;
}
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
const_children_iterator root ( ) const {
......@@ -574,6 +571,47 @@ public:
return os;
}
 
private:
/**
* \brief
* Internal method of printing a tree into a stream
*
* The tree is printed hierarchically.
*
* Example tree a ( b ( c ), b ( c ) ) would be printed like
*
* \-a
* |
* |-b
* | |
* | \-c
* |
* \-b
* |
* \-c
*
* \param os the stream to print to
* \param prefix the auxiliary parameter representing string of paths in the print
* \param last flag indicating this tree is the last subtree of its parent
*/
void nicePrint ( std::ostream & os, std::string prefix, bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << getData ( ) << std::endl;
for ( unsigned int i = 0; i < m_children.size ( ); ++i ) {
os << prefix << "|" << std::endl;
m_children[i].nicePrint ( os, prefix, i == m_children.size ( ) - 1 );
}
}
};
 
template < class T >
......
......@@ -51,25 +51,6 @@ public:
return m_children;
}
 
void nicePrint ( std::ostream & os, std::string prefix, const bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << getData ( ) << std::endl;
for ( unsigned int i = 0; i < m_children.size ( ); ++i ) {
os << prefix << "|" << std::endl;
m_children[i].nicePrint ( os, prefix, i == m_children.size ( ) - 1 );
}
}
typedef typename ext::vector < tree >::const_iterator const_children_iterator;
 
class const_structure_iterator : public std::iterator < std::bidirectional_iterator_tag, T > {
......@@ -83,9 +64,6 @@ public:
const_structure_iterator ( typename ext::vector < tree >::const_iterator n ) : node ( n ), level ( 0 ), virtual_node ( false ), isEnd ( false ) {
}
 
const_structure_iterator ( const const_structure_iterator & other ) : node ( other.node ), level ( other.level ), virtual_node ( other.virtual_node ) {
}
const_structure_iterator & operator ++( ) {
if ( virtual_node ) {
const tree * parent = node->getParent ( );
......@@ -313,18 +291,6 @@ public:
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
private:
const_children_iterator insert_helper ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
tree * under_node = const_cast < tree * > ( & * under );
ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( under_node->getChildren ( ) );
typename ext::vector < tree >::iterator iter = children.insert ( position, begin, end );
for ( typename ext::vector < tree >::iterator iterCopy = iter; begin != end; ++begin, ++iterCopy )
iterCopy->m_parent = under_node;
return iter;
}
template < typename Iterator >
ext::vector < tree > fromIterator ( Iterator begin, Iterator end ) {
ext::vector < tree > res;
......@@ -348,15 +314,22 @@ public:
return insert ( under, position, tree < T > ( value ) );
}
 
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
ext::vector < tree > & children = const_cast < ext::vector < tree > & > ( under->getChildren ( ) );
typename ext::vector < tree >::iterator iter = children.insert ( position, begin, end );
for ( typename ext::vector < tree >::iterator iterCopy = iter; begin != end; ++begin, ++iterCopy )
iterCopy->m_parent = const_cast < tree * > ( & * under );
return iter;
}
template < class Iterator >
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, Iterator begin, Iterator end ) {
ext::vector < tree > children = fromIterator ( begin, end );
 
return insert_helper ( under, position, children.cbegin ( ), children.cend ( ) );
}
const_children_iterator insert ( const_children_iterator under, const_children_iterator position, const_children_iterator begin, const_children_iterator end ) {
return insert_helper ( under, position, begin, end );
return insert ( under, position, children.cbegin ( ), children.cend ( ) );
}
 
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
......@@ -610,6 +583,26 @@ public:
return os;
}
 
private:
void nicePrint ( std::ostream & os, std::string prefix, const bool last ) const {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << getData ( ) << std::endl;
for ( unsigned int i = 0; i < m_children.size ( ); ++i ) {
os << prefix << "|" << std::endl;
m_children[i].nicePrint ( os, prefix, i == m_children.size ( ) - 1 );
}
}
};
 
template < class T >
......
......@@ -52,41 +52,11 @@ public:
return m_children;
}
 
static void nicePrint ( std::ostream & os, const std::pair < const Key, trie < Key, Value > > & data, std::string prefix, const bool last ) {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << data.first << ":" << data.second.getData ( ) << std::endl;
unsigned int i = 0;
for ( const std::pair < const Key, trie < Key, Value > > & subdata : data.second ) {
os << prefix << "|" << std::endl;
nicePrint ( os, subdata, prefix, i == data.second.m_children.size ( ) - 1 );
++i;
}
}
typedef typename ext::map < Key, trie >::const_iterator const_children_iterator;
typedef const trie * const_child_iterator;
 
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
private:
void insert_helper ( const_child_iterator under, const_children_iterator begin, const_children_iterator end ) {
ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( under->getChildren ( ) );
for ( ; begin != end; ++begin )
children.insert ( * begin ).first->second.m_parent = const_cast < trie * > ( & * under );
}
public:
void insert ( const_child_iterator under, Key key, trie < Key, Value > && value ) {
ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( under->getChildren ( ) );
 
......@@ -99,12 +69,14 @@ public:
}
 
void insert ( const_child_iterator under, const_children_iterator begin, const_children_iterator end ) {
insert_helper ( under, begin, end );
ext::map < Key, trie > & children = const_cast < ext::map < Key, trie > & > ( under->getChildren ( ) );
for ( ; begin != end; ++begin )
children.insert ( * begin ).first->second.m_parent = const_cast < trie * > ( & * under );
}
 
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
public:
trie ( Value && data, ext::map < Key, trie > && children ) : m_data ( std::move ( data ) ), m_parent ( nullptr ), m_children ( std::move ( children ) ) {
for ( std::pair < const Key, trie > & child : m_children )
child.second.m_parent = this;
......@@ -227,9 +199,9 @@ public:
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
friend void swap ( trie & first, trie & second ) {
swap ( std::move ( first.m_data ), std::move ( second.m_data ) );
swap ( std::move ( first.m_children ), std::move ( second.m_children ) );
swap ( std::move ( first.m_parent ), std::move ( second.m_parent ) );
swap ( first.m_data, second.m_data );
swap ( first.m_children, second.m_children );
swap ( first.m_parent, second.m_parent );
}
 
// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
......@@ -284,6 +256,28 @@ public:
return os;
}
 
private:
static void nicePrint ( std::ostream & os, const std::pair < const Key, trie < Key, Value > > & data, std::string prefix, const bool last ) {
os << prefix;
if ( last ) {
os << "\\-";
prefix += " ";
} else {
os << "|-";
prefix += "| ";
}
os << data.first << ":" << data.second.getData ( ) << std::endl;
unsigned int i = 0;
for ( const std::pair < const Key, trie < Key, Value > > & subdata : data.second ) {
os << prefix << "|" << std::endl;
nicePrint ( os, subdata, prefix, i == data.second.m_children.size ( ) - 1 );
++i;
}
}
};
 
template < class Key, class Value >
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment