我需要获取字符串的所有唯一子字符串。我已将字符串存储到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
,所以我可以通过任何方式进行迭代,每当我访问任何节点时,我都可以将其打印为唯一的字符串。
答案 0 :(得分:6)
首先,构建一个后缀树。这表示字符串的所有后缀,可以在线性时间内完成。由于每个子字符串都是后缀的前缀,因此现在需要枚举后缀的前缀。
幸运的是,如果两个后缀共享一个公共前缀,则前缀将位于来自root的单个公共路径上,因此树中的根(*)和唯一后缀之间的路径之间存在1-1映射。
因此,在后缀树中从根遍历所有路径以生成所有唯一的子串就足够了。
(*)后缀树中的路径被压缩,即边缘可能代表几个字符。您需要解压缩路径以生成所有子字符串,即将压缩边缘视为多节点路径。
答案 1 :(得分:0)
请注意,myString
的每个子字符串的长度都在0
和strlen(myString)
之间。因此,只需遍历每个可能的长度,以及子串的每个可能的起始位置。
答案 2 :(得分:0)
Trie
中有“结束符号”,即如果某个节点是字符串的最后一个字符,则将其标记为一个terminal
。
因此,如果您需要打印Trie
中的所有字符串,则只需访问dfs()
的节点({1}},就需要Trie
end sign
意思是它是一个终端),你知道它是某个字符串的最后一个字符,所以打印它。