想象一下,我对数组进行了排序:
["A", "B", "C"]
["A", "B", "D"]
["A", "E"]
["F", "G"]
我现在想转换为
type Node struct {
NodeID string
Children []Node
}
我所做的尝试是编写一种通过递归来实现此目的的方法。
这是我目前用Go语言编写的尝试:
func Test_toNodes(t *testing.T) {
in := [][]string{
{"A", "B", "C"},
{"A", "B", "D"},
{"A", "E"},
{"F", "G"},
}
want := []Node{
{
Name: "A",
Children: []Node{
{
Name: "B",
Children: []Node{
{
Name: "C",
},
{
Name: "D",
},
},
},
{
Name: "E",
},
},
},
{
Name: "F",
},
}
got := toNodes(in)
if !reflect.DeepEqual(got, want) {
t.Fatalf("got %v, want %v", got, want)
}
}
func toNodes(in [][]string) []Node {
var (
tmp [][]string
out []Node
)
for i, hierarchy := range in {
current := nodeAt(in, i)
next := nodeAt(in, i+1)
if current == next {
if len(hierarchy) > 0 {
tmp = append(tmp, hierarchy[1:])
}
} else {
out = append(out, Node{
Name: current,
Children: toNodes(tmp),
})
}
}
return out
}
func nodeAt(h [][]string, i int) string {
if i > len(h)-1 {
return ""
}
v := h[i]
if len(v) == 0 {
return ""
}
return v[0]
}
这显然不能提供正确的结果,并且不能处理所有的极端情况-那么是否存在可以在此处应用的一般“算法”?
答案 0 :(得分:1)
这里是递归的解决方案,可传递您的样本输入。您对输入以及可能存在的边缘情况的讨论不多,所以请让我知道输入是否失败并提供输入。
我还在测试中确定了您的预期结果。您忘记了F
节点G
的子节点。希望这会有所帮助。
type Node struct {
Name string
Children []Node
}
func Test_toNodes(t *testing.T) {
in := [][]string{
{"A", "B", "C"},
{"A", "B", "D"},
{"A", "E"},
{"F", "G"},
}
want := []Node{
{
Name: "A",
Children: []Node{
{
Name: "B",
Children: []Node{
{
Name: "C",
},
{
Name: "D",
},
},
},
{
Name: "E",
},
},
},
{
Name: "F",
Children: []Node{
{
Name: "G",
},
},
},
}
got := toNodes(in, 0, 0, len(in))
if !reflect.DeepEqual(got, want) {
t.Fatalf("got %v, want %v", got, want)
}
}
func toNodes(in [][]string, i, j, k int) []Node {
res := []Node{}
for m := j; m < k; m++ {
curr := nodeAt(in, i, m)
next := nodeAt(in, i, m+1)
if next != curr {
children := toNodes(in, i+1, j, m+1)
if len(children) == 0 {
children = nil
}
res = append(res, Node{
Name: curr,
Children: children,
})
j = m + 1
}
}
return res
}
func nodeAt(h [][]string, i, j int) string {
if j >= len(h) || i >= len(h[j]) {
return ""
}
return h[j][i]
}