Algorithm 将字符串数组数组转换为层次结构
假设我对数组进行了排序,如下所示:Algorithm 将字符串数组数组转换为层次结构,algorithm,go,tree,hierarchical,Algorithm,Go,Tree,Hierarchical,假设我对数组进行了排序,如下所示: ["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",
["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]
}
这显然不能呈现正确的结果,也不能处理所有的边缘情况——因此这里有一个通用的“算法”可以应用吗?这里是一个递归解决方案,它传递给您的示例输入。关于输入和可能存在的边缘情况,您没有说太多,所以如果在某些输入上失败,请告诉我,并提供输入 我还修正了你在测试中的预期结果。您忘记了
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]
}
类型节点结构{
名称字符串
子节点[]节点
}
函数测试节点(t*testing.t){
输入:=[]字符串{
{“A”、“B”、“C”},
{“A”、“B”、“D”},
{“A”,“E”},
{“F”,“G”},
}
需要:=[]节点{
{
名称:“A”,
子节点:[]节点{
{
名称:“B”,
子节点:[]节点{
{
名称:“C”,
},
{
名称:“D”,
},
},
},
{
名称:“E”,
},
},
},
{
名称:“F”,
子节点:[]节点{
{
名称:“G”,
},
},
},
}
got:=音调(in,0,0,len(in))
if!reflect.DeepEqual(得到,想要){
t、 Fatalf(“得到%v,想要%v”,得到,想要)
}
}
函数节点(在[]字符串中,i,j,k int)[]节点{
res:=[]节点{}
对于m:=j;m=len(h)| i>=len(h[j]){
返回“”
}
返回h[j][i]
}
欢迎来到SO!您的数据集有多大?最简单的方法是对每个数组,从根开始遍历结构,并在过程中添加任何缺少的子元素。最后,你会有一棵完整的树。但是你会做很多重复的索引。谢谢!对。它不是太大,但我想我可以更聪明地利用数组是排序的这一事实。你可能可以,但问题是,将这些数组放入某种结构中,如前缀树,可以利用这一事实,这可能与直接构建树一样缓慢。