英文:
make a tree from a table using golang?
问题
我想从一个表格中创建一棵树。表格如下所示:
OrgID OrgName parentID
A001 Dept 0 -----顶级
A002 subDept1 A001
A003 sub_subDept A002
A006 gran_subDept A003
A004 subDept2 A001
我希望结果如下所示,使用Go语言如何实现:
<pre>
Dept
--subDept1
----sub_subDept
------gran_subDept
--subDept2
</pre>
英文:
I want to make a tree from a table.
the table is as following:
OrgID OrgName parentID
A001 Dept 0 -----th top
A002 subDept1 A001
A003 sub_subDept A002
A006 gran_subDept A003
A004 subDept2 A001
and i want the result is as following,how to do it using go:
<pre>
Dept
--subDept1
----sub_subDept
------gran_subDept
--subDept2
</pre>
答案1
得分: 10
如果你想将这些行解析为树结构,可以按照以下方式进行:
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
type Node struct {
name string
children []*Node
}
var (
nodeTable = map[string]*Node{}
root *Node
)
func add(id, name, parentId string) {
fmt.Printf("add: id=%v name=%v parentId=%v\n", id, name, parentId)
node := &Node{name: name, children: []*Node{}}
if parentId == "0" {
root = node
} else {
parent, ok := nodeTable[parentId]
if !ok {
fmt.Printf("add: parentId=%v: not found\n", parentId)
return
}
parent.children = append(parent.children, node)
}
nodeTable[id] = node
}
func scan() {
input := os.Stdin
reader := bufio.NewReader(input)
lineCount := 0
for {
lineCount++
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("error reading lines: %v\n", err)
return
}
tokens := strings.Fields(line)
if t := len(tokens); t != 3 {
fmt.Printf("bad input line %v: tokens=%d [%v]\n", lineCount, t, line)
continue
}
add(tokens[0], tokens[1], tokens[2])
}
}
func showNode(node *Node, prefix string) {
if prefix == "" {
fmt.Printf("%v\n\n", node.name)
} else {
fmt.Printf("%v %v\n\n", prefix, node.name)
}
for _, n := range node.children {
showNode(n, prefix+"--")
}
}
func show() {
if root == nil {
fmt.Printf("show: root node not found\n")
return
}
fmt.Printf("RESULT:\n")
showNode(root, "")
}
func main() {
fmt.Printf("main: reading input from stdin\n")
scan()
fmt.Printf("main: reading input from stdin -- done\n")
show()
fmt.Printf("main: end\n")
}
英文:
If you want to parse the lines into a tree structure, this is a way to do it:
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
type Node struct {
name string
children []*Node
}
var (
nodeTable = map[string]*Node{}
root *Node
)
func add(id, name, parentId string) {
fmt.Printf("add: id=%v name=%v parentId=%v\n", id, name, parentId)
node := &Node{name: name, children: []*Node{}}
if parentId == "0" {
root = node
} else {
parent, ok := nodeTable[parentId]
if !ok {
fmt.Printf("add: parentId=%v: not found\n", parentId)
return
}
parent.children = append(parent.children, node)
}
nodeTable[id] = node
}
func scan() {
input := os.Stdin
reader := bufio.NewReader(input)
lineCount := 0
for {
lineCount++
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("error reading lines: %v\n", err)
return
}
tokens := strings.Fields(line)
if t := len(tokens); t != 3 {
fmt.Printf("bad input line %v: tokens=%d [%v]\n", lineCount, t, line)
continue
}
add(tokens[0], tokens[1], tokens[2])
}
}
func showNode(node *Node, prefix string) {
if prefix == "" {
fmt.Printf("%v\n\n", node.name)
} else {
fmt.Printf("%v %v\n\n", prefix, node.name)
}
for _, n := range node.children {
showNode(n, prefix+"--")
}
}
func show() {
if root == nil {
fmt.Printf("show: root node not found\n")
return
}
fmt.Printf("RESULT:\n")
showNode(root, "")
}
func main() {
fmt.Printf("main: reading input from stdin\n")
scan()
fmt.Printf("main: reading input from stdin -- done\n")
show()
fmt.Printf("main: end\n")
}
答案2
得分: 5
根据你的问题和评论提供的信息,可以解决你的问题的是一个普通的递归循环。
package main
import "fmt"
type Org struct {
OrgID string
OrgName string
parentID string
}
func printTree(tbl []Org, parent string, depth int) {
for _, r := range tbl {
if r.parentID == parent {
for i := 0; i < depth; i++ {
fmt.Print("--")
}
fmt.Print(r.OrgName, "\n\n")
printTree(tbl, r.OrgID, depth+1)
}
}
}
func main() {
data := []Org{
{"A001", "Dept", "0 -----th top"},
{"A002", "subDept1", "A001"},
{"A003", "sub_subDept", "A002"},
{"A006", "gran_subDept", "A003"},
{"A004", "subDept2", "A001"},
}
printTree(data, "0 -----th top", 0)
}
结果:
Dept
--subDept1
----sub_subDept
------gran_subDept
--subDept2
Playground: http://play.golang.org/p/27CQAhI8gf
请注意,如果父级是其自己子级的后代,这个递归函数可能会陷入循环中。
英文:
With the information provided in your question and comment, what could solve your problem is an ordinary recursive loop.
package main
import "fmt"
type Org struct {
OrgID string
OrgName string
parentID string
}
func printTree(tbl []Org, parent string, depth int) {
for _, r := range tbl {
if r.parentID == parent {
for i := 0; i < depth; i++ {
fmt.Print("--")
}
fmt.Print(r.OrgName, "\n\n")
printTree(tbl, r.OrgID, depth+1)
}
}
}
func main() {
data := []Org{
{"A001", "Dept", "0 -----th top"},
{"A002", "subDept1", "A001"},
{"A003", "sub_subDept", "A002"},
{"A006", "gran_subDept", "A003"},
{"A004", "subDept2", "A001"},
}
printTree(data, "0 -----th top", 0)
}
Result:
Dept
--subDept1
----sub_subDept
------gran_subDept
--subDept2
Playground: http://play.golang.org/p/27CQAhI8gf
Be aware that this recursive function might get stuck in an loop incase there if a parent is the descendant of its own child.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论