2017-05-05 15 views
4

のうち、構造のようなツリーを取得します。このようなデータ構造で、私は2日以来立ち往生していたパス文字列

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

::私は構造物のようなパスの配列を持っている、と言うことができます

{ 
"name": "a", 
"children": [ 
    { 
     "name": "b", 
     "children": [ 
     { 
     "name": "c", 
     "children": [] 
     }, 
     { 
     "name": "g", 
     "children": [] 
     } 
     ] 
    }, 
    { 
    "name": "d", 
    "children": [] 
    } 
    ] 
} 
:私はこのようなもので終わるしたい
type Node struct { 
    Name  string `json:"name"` 
    Children []Node `json:"children"` 
} 

私はできるだけ早く私は行方不明のノードに(「G」を追加する必要があります何かを実装しようとして、種類の正常に動作再帰、でそれを構築しようとしましたが、唯一の1つの文字列(例:「/ B/C」)について"a/b/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 
    } 
} 

を誰かが効率的なソリューションに私を指すもらえますか?お使いのバージョンから

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

顕著な違い:

+0

[Trie](https:// ja) wikipedia.org/wiki/Trie)や[Radix Tree](https://en.wikipedia.org/wiki/Radix_tree)の挿入アルゴリズムを使用して、あなたが望むものを実装する方法を知ることができます。 – mkopriva

+0

あなたは問題はないが解決策を改善したい場合はcodereview.stackexchangeに同様の質問を投稿することができます –

+0

実際にコードは実際には機能しませんが、私はあなたの提案を試みます – hanneslehmann

答えて

1

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 
} 

出力例は、(私は私のJSONsでnullエントリを好きではないので、私は子供フィールド上omitemptyを使用していることに注意してください) :それは、n個のリストで動作

  • 単一のノードの子の代わりにodesを使用します。これは重要ではありません。バージョンによって、すべてのツリーに同じ単一ルートノード(a)があると想定されている場合があります。あなたのバージョンでそれを処理する唯一の方法は、ルートに "偽の"ノードを置くことです。
  • これは、入力ノードを再利用しません。これは、コードの主な問題の1つです。 (子供)lenの場合> 1、あなたは、入力ノードの名前を更新し、それは子供だし、再帰的に追加します。これは、スライスのすべての前のレベルが子供の一部になることを意味します。代わりに新しいノードを作成する必要があります。
  • 実際にツリーを検索します。ツリーを検索して、挿入されているアイテムが既に存在するかどうかを確認していないので、ノード(特にノードb)を複製します。
+0

非常にクール!早く助けてくれてありがとう!それは動作します。 – hanneslehmann

関連する問題