== Реализация ==
<font color=green>// s public static class Node {{---}} исходный текст</font> <font color=green>// n {{---}} длина текста</font> int begin; <font color=green>// t {{---}} массив, в котором хранится дерево</font> int end; <font color=green> int depth; // sz {{---}} размер суффиксного дерева</font> '''struct distance in characters from root to this node''' l, r, par,linkNode parent; nextNode[]children; '''function''' lenNode suffixLink; Node(int begin, int end, int depth, Node parent):{ '''return''' r - lthis.begin = begin; this.end = end; this.parent = parent; this.depth = depth; children = new Node[ALPHABET.length()]; '''function''' get} } public static Node buildSuffixTree(cCharSequence s):{ '''if''' !next int n = s.countlength(c); next byte[c] a = -1 '''return''' nextnew byte[cn] '''struct state'''; v for (int i = 0; i <font colorn; i++) a[i] =green>// номер вершины, в которой мы остановились на предыдущей итерации</font>(byte) ALPHABET.indexOf(s.charAt(i)); pos <font colorNode root =green>// позиция на метке ребраnew Node(0, ведущего в эту вершину</font> '''state''' ptr(0, 0, null) <font color; Node node =green>// указатель на конец самого длинного не уникального суффикса</font>root; '''function''' go for (stint i = 0, ltail = 0; i < n; i++, rtail++):{ '''while''' l < r Node last = null; '''if''' st.pos while (tail >== t[st.v].len(0){ st Node ch = state(tnode.children[a[st.vi - tail].get(s[l]), 0); '''if''' st.v while (ch !=null && tail >= ch.end -1ch.begin) { '''return''' sttail -= ch.end - ch.begin; '''else''' node = ch; '''if''' s ch = ch.children[ta[st.v].l + st.posi - tail] <tex>\ne</tex> s[l]; '''return''' state(-1, -1) } '''if''' r - l < t[st.v].len(ch == null) - st.pos{ '''return''' statenode.children[a[i]] = new Node(st.vi, n, stnode.pos depth + r node.end - lnode.begin, node); l if (last != l + t[st.v].len(null) - stlast.possuffixLink = node; last = null; st.pos } else { byte t = ta[stch.vbegin + tail].len(); '''return''' st '''function''' split if (st): '''if''' st.pos t == ta[st.vi].len(){ '''return''' st.v ''' if''' st(last != null) last.pos suffixLink == 0 '''return''' t[st.v].par node v = t[st.v]; id = sz break; sz = sz + 1 } else { t[id] Node splitNode = nodenew Node(vch.lbegin, vch.l begin + st.postail, vnode.par) t[vdepth + node.par]end - node.get(s[v.l]begin, node) = id; t[id] splitNode.get(schildren[v.l + st.pos]) = st.v ta[st.vi].par = id t[st.v].l = t[st.v]new Node(i, n, ch.l depth + st.pos '''return''' id '''function''' getLink(vtail, splitNode):; '''if''' splitNode.children[t[v].link <tex>\ne</tex> -1= ch; '''return''' t[v] ch.linkbegin += tail; '''if''' t[v] ch.par depth +== -1tail; '''return''' 0 to ch.parent = getLink(t[v].par)splitNode; '''return''' t[v] node.link = split(go(state(to, tchildren[to].len()), ta[vi - tail].l + (t[v].par=splitNode; if (last !=0null), t[v]last.r)) '''funciton''' treeExtend(pos):suffixLink = splitNode; '''while''' true state nptr last = go(ptr, pos, pos + 1)splitNode; '''if''' nptr.v <tex>\ne</tex> -1 } ptr = nptr} '''return''' mid = splitif (ptr) leaf node = sz sz = sz + 1 t[leaf] = node(pos, n, midroot){ t[mid].get(s[pos]) = leaf --tail; ptr.v = getLink(mid) } else { ptr.pos node = t[ptrnode.v].len() '''if''' !midsuffixLink; '''break'''} '''function''' buildTree(): } sz = 1} '''for''' i = 0...nreturn root; treeExtend(i) }
== См. также==