void SuffixTree::suffix_jump(SuffixTreePoint *point) { SuffixTreePoint old_point = *point; assert(old_point.node_above()->slink() != NULL); point->set_node_above(old_point.node_above()->slink()); point->set_node_below(old_point.node_above()->slink()); point->set_str_depth(point->node_above()->str_depth()); assert(point->str_depth() == old_point.node_above()->str_depth()-1); while (point->str_depth() != old_point.str_depth()-1) { string::size_type text_i = old_point.node_below()->head()+point->str_depth()+1; point->set_node_below(can_descend(point, text[text_i])); assert(point->node_below() != NULL); int diff1 = point->node_below()->str_depth() - point->node_above()->str_depth(); int diff2 = old_point.str_depth()-1 - point->node_above()->str_depth(); if (diff1 <= diff2) { point->set_str_depth(point->str_depth()+diff1); point->set_node_above(point->node_below()); } else { point->set_str_depth(point->str_depth()+diff2); } } /* Now on the new spot. Any suffix links to create? */ if (point->is_node() && last_internal_added != NULL) { last_internal_added->link_to(point->node_above()); last_internal_added = NULL; } }
void SuffixTree::add_suffix(SuffixTreePoint *point, string::size_type start) { SuffixTreeNode *father; if (!point->is_node()) { /* We need to create a new internal node */ SuffixTreeNode *new_internal = get_free_node(start, point->str_depth()); string::size_type below_i = point->node_below()->head()+point->node_above()->str_depth(); assert(below_i < text.size()); assert(point->node_above()->child(text[below_i]) != NULL); point->node_above()->erase_child(text[below_i]); point->node_above()->add_child(text[below_i], new_internal); string::size_type internal_i = point->node_below()->head()+point->str_depth(); assert(internal_i < text.size()); new_internal->add_child(text[internal_i], point->node_below()); if (last_internal_added != NULL) last_internal_added->link_to(new_internal); last_internal_added = new_internal; father = new_internal; } else { father = point->node_above(); } SuffixTreeNode *new_leaf = get_free_node(start, text.size()-start); string::size_type leaf_i = new_leaf->head()+father->str_depth(); assert(leaf_i < text.size()); father->add_child(text[leaf_i], new_leaf); }