Exemplo n.º 1
0
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;
  }
}
Exemplo n.º 2
0
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);
}