生成字符串的所有可能的唯一子字符串

时间:2012-01-09 07:51:46

标签: c++ algorithm data-structures

我需要获取字符串的所有唯一子字符串。我已将字符串存储到trie但我无法弄清楚如何使用它来打印所有唯一的子字符串 例如

字符串aab所有唯一的子字符串都是{"a", "aa", "aab", "ab", "b"}

这是我的trie

代码
#include <iostream>
#include <map>
#include <string>
#include <stack>

struct trie_node_t {
    typedef std::map<char, trie_node_t *> child_node_t;
    child_node_t m_childMap;
    trie_node_t() :m_childMap(std::map<char, trie_node_t*>()) {}

    void insert( std::string& word ) {
        trie_node_t *pNode = this;
        for ( std::string::const_iterator itr = word.begin(); itr != word.end(); ++itr) {
            char letter = *itr;
            if ( pNode->m_childMap.find(letter) == pNode->m_childMap.end()){
                pNode->m_childMap[letter] = new trie_node_t();
            }
            pNode = pNode->m_childMap[letter];
        }
    }

    void print() {
    }
};

int main ( int argc, char **argv ) {
    trie_node_t trie;
    trie.insert(std::string("aab"));
    trie.print();
}

如何实现将打印所有唯一子字符串的print函数。

我正在寻找Linear time approach

由于我已经构建了一个trie,所以我可以通过任何方式进行迭代,每当我访问任何节点时,我都可以将其打印为唯一的字符串。

3 个答案:

答案 0 :(得分:6)

首先,构建一个后缀树。这表示字符串的所有后缀,可以在线性时间内完成。由于每个子字符串都是后缀的前缀,因此现在需要枚举后缀的前缀。

幸运的是,如果两个后缀共享一个公共前缀,则前缀将位于来自root的单个公共路径上,因此树中的根(*)和唯一后缀之间的路径之间存在1-1映射。

因此,在后缀树中从根遍历所有路径以生成所有唯一的子串就足够了。

(*)后缀树中的路径被压缩,即边缘可能代表几个字符。您需要解压缩路径以生成所有子字符串,即将压缩边缘视为多节点路径。

答案 1 :(得分:0)

请注意,myString的每个子字符串的长度都在0strlen(myString)之间。因此,只需遍历每个可能的长度,以及子串的每个可能的起始位置。

答案 2 :(得分:0)

Trie中有“结束符号”,即如果某个节点是字符串的最后一个字符,则将其标记为一个terminal

因此,如果您需要打印Trie中的所有字符串,则只需访问dfs()的节点({1}},就需要Trie end sign意思是它是一个终端),你知道它是某个字符串的最后一个字符,所以打印它。