繁体   English   中英

广义后缀树遍历以找到最长的公共子字符串

[英]Generalised suffix tree traversal to find longest common substring

我正在使用后缀树。 据我所知,我已经正确运行了Ukkonen的算法,可以从任意数量的字符串构建通用后缀树。 我现在正在尝试实现find_longest_common_substring()方法来做到这一点。 为此,我知道我需要找到树中所有字符串之间最深的共享边(以字符为单位,而不是边的深度),并且我已经努力了几天以确保正确的遍历。

现在,我在C ++中拥有以下内容。 我就饶你我所有的代码,但是对于情况下,我让每个节点的边缘的unordered_map称为outgoing_edges ,每边有INTS的矢量recorded_strings包含整数标识添加字符串。 边的child字段是它要去的节点, lr标识其最左和最右的索引。 最后, current_string_number是树中的当前字符串数。

SuffixTree::Edge * SuffixTree::find_deepest_shared_edge(SuffixTree::Node * start, int current_length, int &longest) {
    Edge * deepest_shared_edge = new Edge;
    auto it = start->outgoing_edges.begin();
    while (it != start->outgoing_edges.end()) {
        if (it->second->recorded_strings.size() == current_string_number + 1) {
            int edge_length = it->second->r - it->second->l + 1;
            int path_length = current_length + edge_length;
            find_deepest_shared_edge(it->second->child, path_length, longest);
            if (path_length > longest) {
                longest = path_length;
                deepest_shared_edge = it->second;
            }
        }
        it++;
    }
    return deepest_shared_edge;
}

据我所知,在尝试调试时,遍历通常运行良好,并正确记录了路径长度并设置了最长路径。 但是,由于我不太了解的原因,在最deepest_shared_edge条件下, deepest_shared_edge有时似乎被更新为错误的边缘。 我怀疑我可能不太了解- it->second在整个递归中it->second的更新方式。 但是我不确定如何解决此问题。

我所知道的这个类似的问题,但这种方法似乎十分不同,我不是很确定如何将其应用在这里。

我主要是在这里学习和娱乐,所以我不一定需要工作代码来代替上面的内容-伪代码或对我感到困惑的地方的任何解释也都一样。

您对deepest_shared_edge处理是错误的。 首先,由于从不释放内存,因此在函数开始时进行的分配是内存泄漏。 其次,递归调用的结果将被忽略,因此它找到的最深的边缘都会丢失(尽管您更新了深度,但您并未跟踪最深的边缘)。

要解决此问题,您应该传递deepest_shared_edge作为参考参数(就像您对longest所做的一样),或者可以将其初始化为nullptr ,然后检查您的递归调用是否返回nullptr并进行适当更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM