douyan1896 2017-05-05 13:09
浏览 150
已采纳

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

I am stuck since 2 days, as I am not to firm with pointers and recursion. I have an array of path like structures, lets say:

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

With a data structure like this:

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

I would like to end up with something like this:

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

I tried to build it with a recursion, which works kind of fine, but only for one string (e.g. "a/b/c"), as soon as I try to implement something which should add missing nodes ("g" in "a/b/g") to a tree I am stuck.

I had something like:

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
   }
}

Could someone point me to an efficient solution?

  • 写回答

1条回答 默认 最新

  • douke6424 2017-05-05 16:02
    关注

    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
    }
    

    Example output (note that I used omitempty on the children field, because I don't like null entries in my JSONs):

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

    Notable difference from your version:

    • It operates on a list of nodes instead of the children of a single node. This is important, as your version assumes that all of the trees have the same single root node (a), when this might not be the case. The only way to handle that in your version is to have a "fake" node at the root.
    • It does NOT reuse the input node. This is one of the primary problems with your code. If len(children) > 1, you update the input node's name, append to it's children, then recurse. This means that every prior level of the slice becomes part of the children. You need to create a new node instead.
    • It actually searches the tree. You're not searching the tree to see if the item being inserted already exists, so you duplicate nodes (specifically, node b)
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度