Beispiel #1
0
 public static SuffixTree create(Text text) {
   SuffixTree tree = new SuffixTree(text);
   Suffix active = new Suffix(tree.root, 0, -1);
   for (int i = 0; i < text.length(); i++) {
     tree.addPrefix(active, i);
   }
   return tree;
 }
Beispiel #2
0
  private void addPrefix(Suffix active, int endIndex) {
    Node lastParentNode = null;
    Node parentNode;

    while (true) {
      Edge edge;
      parentNode = active.getOriginNode();

      // Step 1 is to try and find a matching edge for the given node.
      // If a matching edge exists, we are done adding edges, so we break out of this big loop.
      if (active.isExplicit()) {
        edge = active.getOriginNode().findEdge(symbolAt(endIndex));
        if (edge != null) {
          break;
        }
      } else {
        // implicit node, a little more complicated
        edge = active.getOriginNode().findEdge(symbolAt(active.getBeginIndex()));
        int span = active.getSpan();
        if (Objects.equal(symbolAt(edge.getBeginIndex() + span + 1), symbolAt(endIndex))) {
          break;
        }
        parentNode = edge.splitEdge(active);
      }

      // We didn't find a matching edge, so we create a new one, add it to the tree at the parent
      // node position,
      // and insert it into the hash table. When we create a new node, it also means we need to
      // create
      // a suffix link to the new node from the last node we visited.
      Edge newEdge = new Edge(endIndex, text.length() - 1, parentNode);
      newEdge.insert();
      updateSuffixNode(lastParentNode, parentNode);
      lastParentNode = parentNode;

      // This final step is where we move to the next smaller suffix
      if (active.getOriginNode() == root) {
        active.incBeginIndex();
      } else {
        active.changeOriginNode();
      }
      active.canonize();
    }
    updateSuffixNode(lastParentNode, parentNode);
    active.incEndIndex();
    // Now the endpoint is the next active point
    active.canonize();
  }
Beispiel #3
0
 /**
  * Appends a subsequence of the specified text. If the specified character sequence is <code>null
  * </code> this method is equivalent to <code>append("null")</code>.
  *
  * @param txt the text to append or <code>null</code>.
  * @param start the index of the first character to append.
  * @param end the index after the last character to append.
  * @return <code>this</code>
  * @throws IndexOutOfBoundsException if <code>(start < 0) || (end < 0)
  *         || (start > end) || (end > txt.length())</code>
  */
 public final TextBuilder append(Text txt, int start, int end) {
   if (txt == null) return append("null");
   if ((start < 0) || (end < 0) || (start > end) || (end > txt.length()))
     throw new IndexOutOfBoundsException();
   int newLength = _length + end - start;
   while (_capacity < newLength) {
     increaseCapacity();
   }
   for (int i = start, j = _length; i < end; ) {
     char[] chars = _high[j >> B1];
     int dstBegin = j & M1;
     int inc = MathLib.min(C1 - dstBegin, end - i);
     txt.getChars(i, (i += inc), chars, dstBegin);
     j += inc;
   }
   _length = newLength;
   return this;
 }
Beispiel #4
0
 /**
  * Appends the specified text to this text builder. If the specified text is <code>null</code>
  * this method is equivalent to <code>append("null")</code>.
  *
  * @param txt the text to append or <code>null</code>.
  * @return <code>this</code>
  */
 public final TextBuilder append(Text txt) {
   return (txt == null) ? append("null") : append(txt, 0, txt.length());
 }