【问题标题】:generate all possible unique substring of a string生成字符串的所有可能的唯一子字符串
【发布时间】:2012-01-09 07:51:46
【问题描述】:

我需要获取一个字符串的所有唯一子字符串。我已将字符串存储到 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,有没有什么方法可以迭代,每当我访问任何节点时,我都可以将它打印为一个唯一的字符串。

【问题讨论】:

  • 您的代码中存在内存泄漏。在 this 的情况下可能无关紧要,但 ...
  • 严格来说,空字符串也被认为是所有字符串的子字符串。
  • @BlueRaja-DannyPflughoeft:但话又说回来,他需要打印它,每个程序都会打印空字符串:)
  • 可能重复:stackoverflow.com/questions/2560262。后缀树是最适合表示所有唯一子串的结构。即使可能存在 Theta(n^2) 唯一的子字符串,您也可以在线性时间内构建它。

标签: c++ algorithm data-structures


【解决方案1】:

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

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

因此,从后缀树的根开始迭代所有路径就足以产生所有唯一的子字符串。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 它将获取所有子字符串,而不是所有 unique 子字符串。为了得到这些,他需要存储一组现有的字符串,而[在大 O 表示法方面] 最快的方法是......尝试!
    • @amit:啊,好吧 - 我会删除那部分答案。
    • 我正在寻找线性时间方法
    • @Avinash:你不会得到线性时间。考虑字符串“abcd ...”有O(n ^ 2)个子字符串。生成它们将是O(n^2),无论你做什么。
    • @Avinash:线性输入,什么,输入字符串的长度?子串的数量是二次的,所以你要求的是不可能的。
    【解决方案3】:

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

    因此,如果您需要打印Trie 中的所有字符串,则需要在Trie 上使用dfs(),每当使用end sign(这意味着它是一个终端)访问节点时,您知道它是某个字符串的最后一个字符,所以打印它。

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 2019-07-18
      • 2019-03-11
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多