我正在实现一个带有标准插入机制的前缀树。如果我们知道将按字母顺序给出一个单词列表,我们是否可以通过任何方式更改插入以跳过几个步骤?我在Java编码,虽然我不是在寻找任何特定语言的代码。我曾考虑将每个单词的节点添加到队列中,然后向后跳过它直到我们处于下一个单词的前缀,但这可能会绕过前缀树的整个点!
对此类事情的想法?我发现很难想出一个有用的实现,除非输入是许多非常相似的单词("aaaaaaaaaab", "aaaaaaaaaac", "aaaaaaaaaad", ...)
或其他东西。但即便如此,对前缀进行字符串比较可能与正常使用前缀树的成本相似。
答案 0 :(得分:1)
您无法避免查看构建树的输入字符串中的所有字符。如果有办法做到这一点,那么我可能会使你的算法不正确。特别是,假设有一个单词w而你没有看到它的一个字符(比如第k个字符)。然后当你的算法运行并尝试将单词放在trie中的某个地方时,它必须能够在不知道所有字符的情况下放置它。因此,如果我将单词的第k个字符更改为其他字符,您的算法会将其放在与之前完全相同的位置,这是不正确的,因为单词中的某个字符不正确。
由于构造trie的常规算法需要时间与输入中的字符数成比例,因此如果不进行一些疯狂的操作(如并行化构造代码或将字符打包成机器字),您将无法渐近地超越它然后用你的Hammer of Hack Hackery击中它们。
但是,您可能会获得恒定的因子加速。由于缓存性能,链接结构中的大量指针可能会很慢,因此您可以通过最小化必须遵循的指针数来加速算法。您可以做的一件事是保持插入的最后一个字符串结尾的位置,以及跟踪路径返回根目录的节点列表(最好是动态数组)。要插入新角色,您可以执行以下操作:
这样,如果插入大量具有合理长度的公共前缀的单词,则可以避免通过结构的共享部分执行一堆指针追逐。如果你有很多具有相同前缀的单词,这可以为你提供性能提升。它并不比以前更渐近(事实上,使用更多内存),但是不遵循指针可以节省成本。我没有对此进行测试,但似乎它可能会起作用。
希望这有帮助!