使用平衡树 进行运势计算 二: 使用树做计算

160 阅读3分钟

本文已参与 「新人创作礼」 活动,一起开启掘金创作之路。

1 在本小节,我们将使用树做简单的运势推算

如果不清楚计算步骤,请查看这一篇文章 juejin.cn/post/716288… 好了,现在我们知道如何计算,但是怎样管理这些计算呢? 这就需要 运势推算管理器,以此我们可以用来知晓树的结构,哪些节点经过了变化,爻卦中的含义也可以放入其中,方便运势计算时获取。

type TaoBstManager struct {
        *BinarySearchTree
        Bains       []int  //有哪些变化
        Indent      int    //格式化显示
        DefMean     map[int]string //解释方式
        Coordinates map[int]string
}

func MakeNewTreeManager() *TaoBstManager {

        return &TaoBstManager{
                BinarySearchTree: &BinarySearchTree{},
                Indent:           8,
                DefMean:          defMean,
                Coordinates:      Coordinates,
        }
}

func (bsts *TaoBstManager) Trees() *BinarySearchTree {
        return bsts.BinarySearchTree
}

// 遍历树所有节点 到channel
func (bsts *TaoBstManager) IterListNodes() *dlist {

        ccHan := bsts.IterCache()
        Logg.Printf("ccHan size:%v\n", ccHan.Size)
        return IterNodes(ccHan)
}

// 显示所有节点
func (bsts *TaoBstManager) Display() {

        n := 0
        Logg.Printf("%+v\n", bsts) 
        cChans := bsts.IterCache() 
        for i := 0; i < cChans.Size; i++ { //, m :=  cMaps.Size {
                Tnode := cChans.GetNode() // bsts.CacheGets(cChans) 
                n += 1
                if Tnode == nil {
                        Logg.Println("had show all bst node size:", cChans.Size, "after index is nil:", i)
                        continue
                }
                Logg.Printf("the index:%+v\n", i)
        }
        Logg.Println("had after show all bst node size:", len(cChans.Read), "total show:", n)
}

我们知道一爻需要 女大18变,因此需要方法做一变

// 做一变
func (newTree *TaoBstManager) DoOneBian() (*TaoBstManager, int) {

        //一变
        lys := newTree.LeftSize % 4
        if lys == 0 {
                lys = 4
        }
        ldelRst, leftNodeDel := newTree.YaoDel(0, lys) //当左侧长度 除以4的 余数为3时,从左侧删除3个节点

        rys := newTree.RightSize % 4
        if rys == 0 {
                rys = 4
        }
        rdelRst, rightNodeDel := newTree.YaoDel(1, rys+1) //从右节点多删除一个,当作人材的归档,当左侧长度 除以4的 余数为3时,从左侧删除3个节点

        Logg.Printf("del left lys:%v, leftNodeDel:%v del right rys:%v rightNodeDel:%v,\n", lys, leftNodeDel, rys, rightNodeDel)
        Logg.Printf("DoOneBian letf:%v size:%v, right:%v size:%v \n", ldelRst, newTree.LeftSize, rdelRst, newTree.RightSize)
        return newTree, len(leftNodeDel) + len(rightNodeDel)
}

然后我们需要以此做一爻

// 为一爻做一变
func (newManager *TaoBstManager) DoOneBianForYao(env string) *TaoBstManager {

        // 计算随机数,必须在大于4 ~ Max-4 范围内,否则一变失败
        tm, _ := newManager.DoOneBian()
        newTree := tm.Trees()
        mi := newTree.Root.FindMin() //最小
        mx := newTree.Root.FindMax() //最大
        //st := newTree.Size           //总数
        //新的根节点 和以此生成的新的树 作为二变基础
        two := DoRange(mi.Key, mx.Key, env)

        keyNodesTwo := newTree.Searcher(two)
        Logg.Printf("new tree mi:%v mx:%v root:%v node:%v\n", mi, mx, two, keyNodesTwo)
        newTreeTwo := newTree.Rebuild(keyNodesTwo)

        nms := &TaoBstManager{BinarySearchTree: newTreeTwo}

        return nms

}

// 做一爻 三变
func (newManager *TaoBstManager) DoOneYao(env string) int {

        // 计算随机数,必须在大于4 ~ Max-4 范围内,否则一变失败
        newMan := newManager.DoOneBianForYao(env)
        Logg.Printf("newMan of:%v\n", newMan.Size)
        newTwoMan := newMan.DoOneBianForYao(env)
        Logg.Printf("newTwoMan of:%v\n", newTwoMan.Size)

        newThreeMan := newTwoMan.DoOneBianForYao(env)
        Logg.Printf("newThreeMan of:%v, yao:%v, \n whichs deleted:%v \n", newThreeMan.Size, newThreeMan.Size/4, newThreeMan.Bains)

        return newThreeMan.Size / 4
}

以此,我们创建了一爻, 连续6次得到一卦

// 初始化树管理器 并创建六爻
func (bstNew *TaoBstManager) YaoWithReBuild(t int, env string) ([]int, *TaoBstManager) {

        if t <= 0 {
                t = 49
        }
        for i := 0; i < t; i++ {
                bstNew.Puts(i, fmt.Sprintf("suanzi_%v", i))
                Logg.Printf("bstNew :%v, root:%v  len:%v\n  \n", bstNew, bstNew.Root, bstNew.Size)

        }

        var yaoOnes []int

        //得一卦象
        for len(yaoOnes) < 6 {
                // 以人为本 分天地人 查找某个节点 并以此旋转 再平衡
                rootKey := DoRand(t)
                keyNodes := bstNew.Searcher(rootKey) 
                newTree := bstNew.Rebuild(keyNodes)
                caches := newTree.IterCache() 
                if bstNew.Size != newTree.Size {
                        msg := fmt.Sprintf("size error with new tree:%v\n", newTree.Size)
                        panic(msg)
                }
                treeManager := &TaoBstManager{BinarySearchTree: newTree}
                yaoOne := treeManager.DoOneYao(env)
                yaoOnes = append(yaoOnes, yaoOne)
        }

        Logg.Printf("yaoOnes:%v\n", yaoOnes)
        return yaoOnes, bstNew
}


// # 6爻卦象 显示原始卦象, 返回卦值 和 第几卦
func (dt *TaoBstManager) KanGuaOrigin(env string) ([]int, int) {

        fmt.Printf("%v", start)
        guas, bstm := dt.YaoWithReBuild(49, env)
        fmt.Println("卦象已出:")

        yaos, postionChanges := dt.AnysisYaos(guas)

        fmt.Printf("yaos: postionChanges:, %v, %v, bstree:%v\n", yaos, postionChanges, bstm.Size)
        anysis, numb := ICApp.CommonText(yaos)
        fmt.Printf("第%v 卦, \n %v", numb, anysis)
        return yaos, numb

}

小结

好了,到现在为止,我们已经得到了一卦,是不是很简单? 中华5000年的 “核心计算科技” 被计算机很简单的解决啦。 在下一小节,我们将根据计算的爻 组成卦象,并解释其中“深义”。 本文代码地址 github.com/TFrankly/am…

本文已参与 「新人创作礼」 活动,一起开启掘金创作之路。