【问题标题】:suffix tree implementation issue后缀树实现问题
【发布时间】:2015-10-06 21:56:33
【问题描述】:

我正在研究一些后缀树实现,这是一个参考实现,问题是“索引”(参见第 19 行)如何用于类 SuffixTreeNode?我不确定“索引”是否有用,我想我们可能只需要保留所有节点及其子字符值?找不到太多的“索引”值用于类 SuffixTreeNode。

请随时纠正我。任何见解都值得赞赏。

public class SuffixTree {
    SuffixTreeNode root = new SuffixTreeNode();
    public SuffixTree(String s) {
        for (int i = 0; i < s.length(); i++) {
            String suffix = s.substring(i);
            root.insertString(suffix, i);
        }
    }

    public ArrayList<Integer> getIndexes(String s) {
        return root.getIndexes(s);
    }
 }

public class SuffixTreeNode {
    HashMap<Character, SuffixTreeNode> children = new
    HashMap<Character, SuffixTreeNode>();
    char value;
    ArrayList<Integer> indexes = new ArrayList<Integer>();
    public SuffixTreeNode() { }

    public void insertString(String s, int index) {
        indexes.add(index);
        if (s != null && s.length() > 0) {
            value = s.charAt(0);
            SuffixTreeNode child = null;
            if (children.containsKey(value)) {
                child = children.get(value);
            } else {
                child = new SuffixTreeNode();
                children.put(value, child);
            }
            String remainder = s.substring(1);
            child.insertString(remainder, index);
        }
    }

    public ArrayList<Integer> getIndexes(String s) {
        if (s == null || s.length() == 0) {
            return indexes;
        } else {
            char first = s.charAt(0);
            if (children.containsKey(first)) {
                String remainder = s.substring(1);
                return children.get(first).getIndexes(remainder);
            }
        }
        return null;
    }
}

public class Question {
    public static void main(String[] args) {
        String testString = “mississippi”;
        String[] stringList = {“is”, “sip”, “hi”, “sis”};
        SuffixTree tree = new SuffixTree(testString);
        for (String s : stringList) {
            ArrayList<Integer> list = tree.getIndexes(s);
            if (list != null) {
                System.out.println(s + “: “ + list.toString());
            }
        }
    }
}

【问题讨论】:

  • 我运行了您的代码,它按设计运行。如果你有一个错误,假设你没有减少字符串,你会得到一个 stackoverflow 异常,因为你永远不会遇到你的递归基本情况并陷入永远循环

标签: java algorithm trie suffix-tree


【解决方案1】:

indexes 对于您正在查看的后缀树的实现肯定需要(有多个版本的后缀树,其中一些版本比其他版本更优化)。 indexes 变量在将原始字符串 (mississippi) 中存在子字符串 (is, sip, hi, sis) 的索引返回给调用方法方面发挥着不可或缺的作用。 getIndexes 在其基本情况下返回 indexes,这是您获取每个子字符串出现列表的方式。见下面的输出

is: [1, 4]
sip: [6]
sis: [3]

【讨论】:

  • @Lin Ma 在递归方法中使用了一个基本案例。这是告诉递归调用停止调用自身并返回堆栈的条件。基本情况是代码中的第 39 行。不,在第 4-6 行的 for 循环中没有增加错误索引。
  • @LinMa 看看生成的输出,单步执行代码,就好像你是编译器一样,你会理解它。查看子字符串“is”,它会在 1 和 4 处打印出正确的索引
  • @LinMa 我讨厌这样回答,但是;确实,您必须说服/证明自己应用程序正在递归地做什么。我建议研究递归问题,youtube 上有很多很好的教程。它将需要多个视频,你不会在一个之后得到它
  • @LinMa 我没有完全理解你的解释,但它是这样的。是的,你是完全正确的索引意味着匹配的开始。对于子字符串“sip”,索引是 6,因为在原始单词中,索引 6 是匹配的开始,即在元素 [6][7][8] 中。与子字符串“is”相同,它具有索引 1 和 4,因为在原始单词中,您在这些位置匹配了该子字符串。如果您发现我的解决方案有帮助,并且如果它回答了您的原始问题,请不要忘记接受。如果您还需要什么,请告诉我
猜你喜欢
  • 2011-09-14
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 2012-02-18
  • 2010-11-01
  • 2011-05-27
  • 2010-09-15
  • 2017-09-22
相关资源
最近更新 更多