Java 为什么这个迭代的trie遍历不能在查询时生成正确的单词?

Java 为什么这个迭代的trie遍历不能在查询时生成正确的单词?,java,string,algorithm,data-structures,trie,Java,String,Algorithm,Data Structures,Trie,所以,我的困境是:我试图遍历一个trie数据结构来找到第n个单词 对于那些不熟悉trie的人来说,trie是一种基于压缩的数据结构,允许您插入一系列单词,并按字典顺序对它们进行排序,但每个节点都是它自己的单个字母,从而将其分支并拼写到相应的单词中(如果不清楚,请有更具体定义的人修复!) 树中的每个节点都有一个26个节点的数组,表示字母表中的26个字母。单词拼写完成后,数组(isWord)中最后一个字符的布尔值将标记为true。例如{a,are,art}等词中的词也是如此;“a”是一个单词,因此,

所以,我的困境是:我试图遍历一个trie数据结构来找到第n个单词

对于那些不熟悉trie的人来说,trie是一种基于压缩的数据结构,允许您插入一系列单词,并按字典顺序对它们进行排序,但每个节点都是它自己的单个字母,从而将其分支并拼写到相应的单词中(如果不清楚,请有更具体定义的人修复!)

树中的每个节点都有一个26个节点的数组,表示字母表中的26个字母。单词拼写完成后,数组(isWord)中最后一个字符的布尔值将标记为true。例如{a,are,art}等词中的词也是如此;“a”是一个单词,因此,此字母的isWord设置为true。然而,“和”中的字母被钉在“a”上,“d”被标记为一个单词

既然引言已经准备好了,我的问题是:我很难递归地做这件事,所以我试着迭代地做。我非常非常接近这个解决方案,但是由于某种原因,当我调用nthWord(intn)时,一些单词被跳过了。本质上,该方法应该遍历树(根据trie属性按字母顺序排列),并找到名称所暗示的第n个单词。但是,如前所述,有时该方法跳过trie中的单词,即使它保证它们被添加到trie中(而且isWord Boolean也总是正确的)。我已经解决这个问题三天了,我真是迷路了

我希望输出是序列中的第n个单词(来自一个非常大的.txt文件),但有时它会跳过某些单词。如果j被分配到-1,则以2开头的“土豚”等单词将被考虑,但其他单词将被跳过。相反,如果将其指定为0,则会考虑其他单词,但会跳过以两个相同字母开头的单词


编辑:我还应该声明第n个单词(…)方法不会处理重复的单词。Trie将每个单词的频率存储在所述单词的最后一个字符中。因此,在这种情况下,重复的单词不是问题。

这里是这个问题的递归解决方案(更直观)。只需将其视为一个树问题,您必须从左到右遍历树,然后尝试查找N第个单词

您可以从根节点创建DFS。保留一个变量来存储到目前为止您访问过的单词数(您访问过的带有isWord的节点数)。并在到达N第个单词时返回该单词

代码应该是这样的。我刚刚编写了一个模板代码-

def findWord(TrieNode,word):
    global N
    if TrieNode.isWord:
        if N == 0:
            return word
        else:
            N -= 1

    for each in TrieNode.children:
        if each is not None:
            word += each.character
            res = findWord(N,each,word)
            if len(res) > 0:
                return res
            word = word[:-1]
    return ''
N = input()
findWord(root,'')

这里是这个问题的递归解决方案(更直观)。只需将其视为一个树问题,您必须从左到右遍历树,然后尝试查找N第个单词

您可以从根节点创建DFS。保留一个变量来存储到目前为止您访问过的单词数(您访问过的带有isWord的节点数)。并在到达N第个单词时返回该单词

代码应该是这样的。我刚刚编写了一个模板代码-

def findWord(TrieNode,word):
    global N
    if TrieNode.isWord:
        if N == 0:
            return word
        else:
            N -= 1

    for each in TrieNode.children:
        if each is not None:
            word += each.character
            res = findWord(N,each,word)
            if len(res) > 0:
                return res
            word = word[:-1]
    return ''
N = input()
findWord(root,'')


您是否反对添加一个
num\u子体
字段?这将使此操作更快、更容易。多个子体表示一个节点有多少个子节点?那怎么会更容易呢?另外,我很好奇它是如何实现的,因为我必须在添加字符时返回树以增加“后代数”变量…你永远不必提升。@JoshuaCrotts你能定义什么是
n
th单词吗?是您添加到trie中的第
n
个单词,还是在完成trie构造后的第
n
个单词?如果是前者,只需使用一个映射。如果是1索引的,abcd不会在azzz之前出现。我不确定我是否理解,您是否反对添加
num\u子体
字段?这将使此操作更快、更容易。多个子体表示一个节点有多少个子节点?那怎么会更容易呢?另外,我很好奇它是如何实现的,因为我必须在添加字符时返回树以增加“后代数”变量…你永远不必提升。@JoshuaCrotts你能定义什么是
n
th单词吗?是您添加到trie中的第
n
个单词,还是在完成trie构造后的第
n
个单词?如果是前者,只需使用一个映射。如果是1索引的,abcd不会在azzz之前出现。我不确定我是否理解这个解决方案的唯一问题是我本身没有“children”变量;它不是一个链表,而是一个节点数组(未使用的字母被分配为null)。我可以从0循环到25吗(因为每个节点都有26个节点的数组)?在你的例子中,你有字母[],我基本上是在那里迭代一个节点数组。你是对的,我会试试这个,看看它是否有效。我很快就回来报到!酷,让我知道,如果你不是Python的人,你需要更多关于任何代码行的解释2-1,我不明白为什么函数中的变量
search
k
在你的代码中。只需全局使用k,并在找到单词时将其减量。2,你必须遍历所有的子节点,即使你到达的节点不是一个单词。这个解决方案唯一的问题是我没有一个“children”变量本身;它不是一个链表,而是一个节点数组(未使用的字母被分配为null)。我可以从0循环到25吗(因为每个节点都有一个26个节点的数组)?在你的例子中,你有字母[],我基本上在那里迭代一个节点数组。你是ri