Task: Suffix tree



C#: using System;
using System.Collections.Generic;

namespace SuffixTree {
    class Node {
        public string sub;                     
        public List<int> ch = new List<int>(); 

        public Node() {
            sub = "";
        }

        public Node(string sub, params int[] children) {
            this.sub = sub;
            ch.AddRange(children);
        }
    }

    class SuffixTree {
        readonly List<Node> nodes = new List<Node>();

        public SuffixTree(string str) {
            nodes.Add(new Node());
            for (int i = 0; i < str.Length; i++) {
                AddSuffix(str.Substring(i));
            }
        }

        public void Visualize() {
            if (nodes.Count == 0) {
                Console.WriteLine("<empty>");
                return;
            }

            void f(int n, string pre) {
                var children = nodes[n].ch;
                if (children.Count == 0) {
                    Console.WriteLine("- {0}", nodes[n].sub);
                    return;
                }
                Console.WriteLine("+ {0}", nodes[n].sub);

                var it = children.GetEnumerator();
                if (it.MoveNext()) {
                    do {
                        var cit = it;
                        if (!cit.MoveNext()) break;

                        Console.Write("{0}+-", pre);
                        f(it.Current, pre + "| ");
                    } while (it.MoveNext());
                }

                Console.Write("{0}+-", pre);
                f(children[children.Count-1], pre+"  ");
            }

            f(0, "");
        }

        private void AddSuffix(string suf) {
            int n = 0;
            int i = 0;
            while (i < suf.Length) {
                char b = suf[i];
                int x2 = 0;
                int n2;
                while (true) {
                    var children = nodes[n].ch;
                    if (x2 == children.Count) {
                        
                        n2 = nodes.Count;
                        nodes.Add(new Node(suf.Substring(i)));
                        nodes[n].ch.Add(n2);
                        return;
                    }
                    n2 = children[x2];
                    if (nodes[n2].sub[0] == b) {
                        break;
                    }
                    x2++;
                }
                
                var sub2 = nodes[n2].sub;
                int j = 0;
                while (j < sub2.Length) {
                    if (suf[i + j] != sub2[j]) {
                        
                        var n3 = n2;
                        
                        n2 = nodes.Count;
                        nodes.Add(new Node(sub2.Substring(0, j), n3));
                        nodes[n3].sub = sub2.Substring(j); 
                        nodes[n].ch[x2] = n2;
                        break; 
                    }
                    j++;
                }
                i += j; 
                n = n2; 
            }
        }
    }

    class Program {
        static void Main() {
            new SuffixTree("banana$").Visualize();
        }
    }
}





Python: class Node:
    def __init__(self, sub="", children=None):
        self.sub = sub
        self.ch = children or []

class SuffixTree:
    def __init__(self, str):
        self.nodes = [Node()]
        for i in range(len(str)):
            self.addSuffix(str[i:])

    def addSuffix(self, suf):
        n = 0
        i = 0
        while i < len(suf):
            b = suf[i]
            x2 = 0
            while True:
                children = self.nodes[n].ch
                if x2 == len(children):
                    
                    n2 = len(self.nodes)
                    self.nodes.append(Node(suf[i:], []))
                    self.nodes[n].ch.append(n2)
                    return
                n2 = children[x2]
                if self.nodes[n2].sub[0] == b:
                    break
                x2 = x2 + 1

            
            sub2 = self.nodes[n2].sub
            j = 0
            while j < len(sub2):
                if suf[i + j] != sub2[j]:
                    
                    n3 = n2
                    
                    n2 = len(self.nodes)
                    self.nodes.append(Node(sub2[:j], [n3]))
                    self.nodes[n3].sub = sub2[j:] 
                    self.nodes[n].ch[x2] = n2
                    break 
                j = j + 1
            i = i + j   
            n = n2      

    def visualize(self):
        if len(self.nodes) == 0:
            print "<empty>"
            return

        def f(n, pre):
            children = self.nodes[n].ch
            if len(children) == 0:
                print "--", self.nodes[n].sub
                return
            print "+-", self.nodes[n].sub
            for c in children[:-1]:
                print pre, "+-",
                f(c, pre + " | ")
            print pre, "+-",
            f(children[-1], pre + "  ")

        f(0, "")

SuffixTree("banana$").visualize()