从路径字符串中获取类似树形结构的内容

7

我已经卡了两天了,因为我不太熟悉指针和递归。我有一个路径结构的数组,比如:

s:=[]string {
  "a/b/c",
  "a/b/g",
  "a/d",
}

使用这样的数据结构:

 type Node struct {
   Name     string `json:"name"`
   Children []Node `json:"children"`
}

我希望最终的结果是这样的:

{
 "name": "a",
 "children": [
     {
      "name": "b",
      "children": [
        {
         "name": "c",
         "children": []
        },
        {
         "name": "g",
         "children": []
        }
      ]
    },
    {
     "name": "d",
     "children": []
    }
  ]
}

我尝试使用递归来构建它,对于一个字符串(例如:“a/b/c”)它可以工作得相当好。但是,一旦我尝试实现一些应该添加缺失节点(“a/b/g”中的“g”)到树中的东西时,我就卡住了。
我有类似以下的代码:
func appendChild(root Node, children []string) Node {
   if len(children) == 1 {
      return Node{children[0], nil}
   } else {
      t := root
      t.Name=children[0]
      t.Children = append(t.Children, appendChild(root, children[1:]))
      return t
   }
}

有人能给我指出一个高效的解决方案吗?


你可以通过谷歌搜索TrieRadix Tree插入算法来了解如何实现你想要的功能。 - mkopriva
如果您没有问题,但想要改进您的解决方案,可以将类似的问题发布到codereview.stackexchange。 - Gujarat Santana
实际上这段代码并没有真正起作用,但我会尝试你的建议。 - hanneslehmann
1个回答

6

https://play.golang.org/p/9pER5cwChF

func AddToTree(root []Node, names []string) []Node {
    if len(names) > 0 {
        var i int
        for i = 0; i < len(root); i++ {
            if root[i].Name == names[0] { //already in tree
                break
            }
        }
        if i == len(root) {
            root = append(root, Node{Name: names[0]})
        }
        root[i].Children = AddToTree(root[i].Children, names[1:])
    }
    return root
}

示例输出(请注意,我在子字段上使用了omitempty,因为我不喜欢我的JSON中出现null条目):

[{
    "name": "a",
    "children": [{
        "name": "b",
        "children": [{
            "name": "c"
        }, {
            "name": "g"
        }]
    }, {
        "name": "d"
    }]
}]

与你的版本相比,有显著差异:

  • 它在一组节点上操作,而不是单个节点的子节点。这很重要,因为你的版本假设所有树都有相同的单个根节点(a),但实际上可能并非如此。在你的版本中处理这个问题的唯一方法是在根处创建一个“虚拟”节点。
  • 它不会重用输入节点。这是你的代码的主要问题之一。如果len(children) > 1,则更新输入节点的名称,将其添加到其子节点中,然后进行递归。这意味着之前每个级别的切片都成为了子项的一部分。你需要创建一个节点。
  • 它实际上搜索树。你没有搜索树以查看插入的项是否已经存在,因此会产生重复节点(特别是节点b)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接