OK,有两个问题在OP的实现:
- if块检查孩子存在的行动应该“继续”的循环,而不是返回的话,结果(尝试其他的树枝) 。
- if block条件检查当前节点是否是终端(字)必须改变,以适应github.com/derekparker/trie作者的设计决定,将终端节点存储为与最后一个字母对应的节点的子节点这个词,作为0符文在其父母中键入。
这里的工作版本:
func FindAllWords(letters []rune, node *trie.Node, curString string) []string {
words := []string{}
for i, let := range letters {
n, ok := node.Children()[let]
if !ok {
continue
}
curWord := curString + string(n.Val())
newLetters := []rune{}
newLetters = append(newLetters, letters[:i]...)
newLetters = append(newLetters, letters[i+1:]...)
if n.Children()[0x0] != nil {
words = append(words, curWord)
}
words = append(words, FindAllWords(newLetters, n, curWord)...)
}
return words
}
这里有一个稍微更可读的版本(合我的口味,当然):
func FindAllWords2(s string, n *trie.Node, w string) []string {
r := []string{}
for i, l := range s {
n1, ok := n.Children()[l]
if !ok {
continue
}
s1 := s[:i] + s[i+1:]
w1 := w + string(l)
if n1.Children()[0x0] != nil {
r = append(r, w1)
}
r = append(r, FindAllWords2(s1, n1, w1)...)
}
return r
}
第二个问题当然是从依赖于未来的一个具有漏洞的API的外部库,它将实现细节公开给客户端代码。
为了避免这样那样的麻烦,这个简单的例子,我建议建立一个简单的线索实现能来,因为这很容易:
type Node struct {
Char rune
Term bool
Children map[rune]*Node
}
func (n *Node) Add(s []rune) {
if len(s) == 0 {
n.Term = true
return
}
r := s[0]
c, ok := n.Children[r]
if !ok {
c = &Node{Char: r, Children: make(map[rune]*Node)}
n.Children[r] = c
}
c.Add(s[1:])
}
func Empty() *Node {
return &Node{Children: make(map[rune]*Node)}
}
使用结构,这是我如何装载一个英语单词表:
func English() *Node {
f, err := os.Open("/usr/share/dict/american-english")
if err != nil {
panic(err)
}
defer f.Close()
t := Empty()
s := bufio.NewScanner(f)
for s.Scan() {
t.Add([]rune(strings.ToLower(s.Text())))
}
return t
}
这种结构可以在同一个算法中使用极少的修改,并没有实现misteries:
func FindAllWords3(s string, n *Node, w string) []string {
r := []string{}
for i, l := range s {
n1, ok := n.Children[l]
if !ok {
continue
}
s1 := s[:i] + s[i+1:]
w1 := w + string(l)
if n1.Term {
r = append(r, w1)
}
r = append(r, FindAllWords3(s1, n1, w1)...)
}
return r
}
以下是上述加于字“舞”和上面加载相同的单词表英语的三种实现的结果:
[d dan dance dances dane danes dean deans den dena dens dec a ad aden ads an and andes ac acne ace aced aces as ascend n nd na ne ned c cd ca cad cads can cane caned canes cans case cased cs e ed edna end ends es s sad sade san sand sane sac sn snead sc scad scan se sedan sedna sea sean sen send sec]
[d dan dance dances dane danes dean deans den dena dens dec a ad aden ads an and andes ac acne ace aced aces as ascend n nd na ne ned c cd ca cad cads can cane caned canes cans case cased cs e ed edna end ends es s sad sade san sand sane sac sn snead sc scad scan se sedan sedna sea sean sen send sec]
[d dan dance dances dane danes dean deans den dena dens dec a ad aden ads an and andes ac acne ace aced aces as ascend n nd na ne ned c cd ca cad cads can cane caned canes cans case cased cs e ed edna end ends es s sad sade san sand sane sac sn snead sc scad scan se sedan sedna sea sean sen send sec]
当您尝试使用该代码会发生什么?它是否有错误或给出不正确的结果? – MathSquared
什么是错误? –
我只是得到一个空片返回。我非常肯定,第8行需要中断而不是返回,正如jdd0指出的那样,但这并不能解决问题。 – William