Task: Suffix tree




Go: package main

import "fmt"

func main() {
    vis(buildTree("banana$"))
}

type tree []node

type node struct {
    sub string 
    ch  []int  
}

func buildTree(s string) tree {
    t := tree{node{}} 
    for i := range s {
        t = t.addSuffix(s[i:])
    }
    return t
}

func (t tree) addSuffix(suf string) tree {
    n := 0
    for i := 0; i < len(suf); {
        b := suf[i]
        ch := t[n].ch
        var x2, n2 int
        for ; ; x2++ {
            if x2 == len(ch) {
                
                n2 = len(t)
                t = append(t, node{sub: suf[i:]})
                t[n].ch = append(t[n].ch, n2)
                return t
            }
            n2 = ch[x2]
            if t[n2].sub[0] == b {
                break
            }
        }
        
        sub2 := t[n2].sub
        j := 0
        for ; j < len(sub2); j++ {
            if suf[i+j] != sub2[j] {
                
                n3 := n2
                
                n2 = len(t)
                t = append(t, node{sub2[:j], []int{n3}})
                t[n3].sub = sub2[j:] 
                t[n].ch[x2] = n2
                break 
            }
        }
        i += j 
        n = n2 
    }
    return t
}

func vis(t tree) {
    if len(t) == 0 {
        fmt.Println("<empty>")
        return
    }
    var f func(int, string)
    f = func(n int, pre string) {
        children := t[n].ch
        if len(children) == 0 {
            fmt.Println("╴", t[n].sub)
            return
        }
        fmt.Println("┐", t[n].sub)
        last := len(children) - 1
        for _, ch := range children[:last] {
            fmt.Print(pre, "├─")
            f(ch, pre+"│ ")
        }
        fmt.Print(pre, "└─")
        f(children[last], pre+"  ")
    }
    f(0, "")
}


Java: import java.util.ArrayList;
import java.util.List;

public class SuffixTreeProblem {
    private static class Node {
        String sub = "";                       
        List<Integer> ch = new ArrayList<>();  
    }

    private static class SuffixTree {
        private List<Node> nodes = new ArrayList<>();

        public SuffixTree(String str) {
            nodes.add(new Node());
            for (int i = 0; i < str.length(); ++i) {
                addSuffix(str.substring(i));
            }
        }

        private void addSuffix(String suf) {
            int n = 0;
            int i = 0;
            while (i < suf.length()) {
                char b = suf.charAt(i);
                List<Integer> children = nodes.get(n).ch;
                int x2 = 0;
                int n2;
                while (true) {
                    if (x2 == children.size()) {
                        
                        n2 = nodes.size();
                        Node temp = new Node();
                        temp.sub = suf.substring(i);
                        nodes.add(temp);
                        children.add(n2);
                        return;
                    }
                    n2 = children.get(x2);
                    if (nodes.get(n2).sub.charAt(0) == b) break;
                    x2++;
                }
                
                String sub2 = nodes.get(n2).sub;
                int j = 0;
                while (j < sub2.length()) {
                    if (suf.charAt(i + j) != sub2.charAt(j)) {
                        
                        int n3 = n2;
                        
                        n2 = nodes.size();
                        Node temp = new Node();
                        temp.sub = sub2.substring(0, j);
                        temp.ch.add(n3);
                        nodes.add(temp);
                        nodes.get(n3).sub = sub2.substring(j);  
                        nodes.get(n).ch.set(x2, n2);
                        break;  
                    }
                    j++;
                }
                i += j;  
                n = n2;  
            }
        }

        public void visualize() {
            if (nodes.isEmpty()) {
                System.out.println("<empty>");
                return;
            }
            visualize_f(0, "");
        }

        private void visualize_f(int n, String pre) {
            List<Integer> children = nodes.get(n).ch;
            if (children.isEmpty()) {
                System.out.println("- " + nodes.get(n).sub);
                return;
            }
            System.out.println("┐ " + nodes.get(n).sub);
            for (int i = 0; i < children.size() - 1; i++) {
                Integer c = children.get(i);
                System.out.print(pre + "├─");
                visualize_f(c, pre + "│ ");
            }
            System.out.print(pre + "└─");
            visualize_f(children.get(children.size() - 1), pre + "  ");
        }
    }

    public static void main(String[] args) {
        new SuffixTree("banana$").visualize();
    }
}