Go 如何读取文本文件并基于这些值实现树?

Go 如何读取文本文件并基于这些值实现树?,go,data-structures,Go,Data Structures,我试图使用Go实现DFS(深度优先搜索)算法,但我的实际代码需要逐个节点手动添加以构建树。我想读取包含以下数据的文本文件(示例): 并用这些值构建树。根值将是75、左95、右64,依此类推 这是我的完整代码: //包main实现DFS算法 包干管 进口( “布菲奥” “旗帜” “fmt” “日志” “操作系统” “strconv” “字符串” “同步” ) //节点处理所有树数据 类型节点结构{ 数据接口{} 左*节点 右*节点 } //NewNode为树创建一个新节点 func NewNode

我试图使用Go实现DFS(深度优先搜索)算法,但我的实际代码需要逐个节点手动添加以构建树。我想读取包含以下数据的文本文件(示例):

并用这些值构建树。根值将是75、左95、右64,依此类推

这是我的完整代码:

//包main实现DFS算法
包干管
进口(
“布菲奥”
“旗帜”
“fmt”
“日志”
“操作系统”
“strconv”
“字符串”
“同步”
)
//节点处理所有树数据
类型节点结构{
数据接口{}
左*节点
右*节点
}
//NewNode为树创建一个新节点
func NewNode(数据接口{})*节点{
节点:=新建(节点)
node.Data=Data
node.Left=nil
node.Right=nil
返回节点
}
//FillNodes基于文件中的每个值创建所有节点
func FillNodes(行*[]字符串){
节点:=*行
rootInt,:=strconv.Atoi(节点[0][0])
根:=NewNode(rootInt)
//在此处添加值
工作组.添加(1)
转到root.DFS()
wg.Wait()
}
//ProcessNode检查并打印实际节点
func(n*Node)ProcessNode(){
推迟工作组完成()
var hello[]int
对于i:=0;i<10000;i++{
hello=append(hello,i)
}
fmt.Printf(“节点%v\n”,n.Data)
}
//DFS在每个节点上调用自身
func(n*节点)DFS(){
推迟工作组完成()
如果n==nil{
返回
}
工作组.添加(1)
向左走
工作组.添加(1)
gon.ProcessNode()
工作组.添加(1)
向右走
}
//检查错误句柄错误检查
func CheckError(错误错误){
如果错误!=零{
log.Fatal(错误)
}
}
//OpenFile句柄从文本文件读取数据
func OpenFile()[]字符串{
变量行[][]字符串
ftpr:=flag.String(“fpath”、“pyramid2.txt”和“/pyramid2.txt”)
flag.Parse()
f、 错误:=操作系统打开(*ftpr)
检查错误(err)
延迟函数(){
如果错误:=f.Close();错误!=nil{
log.Fatal(错误)
}
}()
s:=bufio.NewScanner(f)
对于s.Scan(){
行:=strings.Fields(s.Text())
行=追加(行,行)
}
err=s.err()
检查错误(err)
回程线
}
var wg sync.WaitGroup
//Main创建树并调用DFS
func main(){
节点:=OpenFile()
填充节点(&nodes)
}

解决这个问题的可能办法是什么?另外,我如何能够轻松地将所有这些字符串转换为int?

这里有一个创建树的方法(没有测试它):

如果这是为了生产,我的建议是对其进行TDD,并正确处理所有错误,并决定您的软件应该如何处理每一个错误。您还可以编写一些基准测试,然后使用goroutines优化算法(如果适用)

按照你现在的做法,你最好不去参加社交活动: 假设你有一棵巨大的树,有1M个节点,DFS func将递归地启动1M个goroutine,每个goroutine都有一个额外的内存和CPU成本,而不需要做很多工作来证明它的合理性。您需要一种更好的方法来拆分工作,以便在更少的goroutine上完成,每个goroutine可能有10000个节点


我强烈建议您编写一个没有goroutine的版本,研究它的复杂性,编写基准测试来验证预期的复杂性。一旦你有了这些,就开始寻找一种引入goroutine的策略,并验证它比你已有的更有效。

在第二层95和64应该有4个子层,但在第三层只有3个,我们如何发现它们属于每个节点?47属于两个节点。。。在最终版本中,可以读取此文件并确定最大金额的“路由”。作为第一步,我建议您删除waitgroups和GoRoutine。你是在问如何在树中搜索,还是如何构建树?为什么?好的,首先我需要建立一棵树,然后再进行搜索。工作得很有魅力!不,这是一个挑战,我自己做了,但我放弃了。。。但总有一天我会实现测试,我也需要在Go上学习单元测试!谢谢你的帮助。为什么ProcessNode func只打印七次?我错过了一些关于这个实现的东西?你可以给我一个如何实现我的目标的提示吗?我需要得到这棵树的最大值,但我真的陷入了困境。任何出发点我都会感激!好的,现在我在尝试访问第七个节点时遇到一个无效内存地址错误。嗨,我编辑了FillLevel代码,结果发现我不止一次添加了一些节点,我想现在可以了。关于DFS func,在您的代码中,您没有调用wg。在任何地方等待,您应该wg。等待所有的goroutine完成,它只打印7次,因为在主线程完成之前,所有例程都可以这样做
75
95 64
17 47 82
18 35 87 10
20 04 83 47 65
func FillLevel(parents []*Node, level []string) (children []*Node, err error){
    if len(parents) + 1 != len(level) {
        return nil, errors.New("params size not OK")
    }

    for i, p := range parents {
        leftVal, err := strconv.Atoi(level[i])
        rightVal, err := strconv.Atoi(level[i+1])
        if err != nil {
            return nil, err
        }

        p.Left = NewNode(leftVal)
        p.Right = NewNode(rightVal)
        children = append(children, p.Left)
        if i == len(parents) - 1 {
            children = append(children, p.Right)
        }
    }
    return children, nil
}

func FillNodes(lines *[][]string) (*Node, error){
    nodes := *lines

    rootInt, _ := strconv.Atoi(nodes[0][0])
    root := NewNode(rootInt)

    // add the values here
    parents := []*Node{root}
    for _, level := range nodes[1:] {
        parents, _ = FillLevel(parents, level)
    }
    return root, nil
}

func main() {
    nodes := OpenFile()
    r, _ := FillNodes(&nodes)
    wg.Add(1)
    r.DFS()
    wg.Wait()
}