Go 如何使用不同的数据结构递归循环映射

Go 如何使用不同的数据结构递归循环映射,go,Go,我试图找出递归地遍历go中的[string]int映射的最佳方法。我正在构建一个游戏,其中涉及多个国家,最终由两人一组进行分组 目标是将“得分”最低的前两个国家匹配到自己的两个组中,并将其添加到集合中,为新地图提供这些国家得分的总值 然后递归地对所有组执行该操作,最终得到一个组和一个总值 例如,如果您有: score := map[string]int{ "Canada": 7, "US": 2, "Germany": 3, "Ko

我试图找出递归地遍历go中的
[string]int
映射的最佳方法。我正在构建一个游戏,其中涉及多个国家,最终由两人一组进行分组

目标是将“得分”最低的前两个国家匹配到自己的两个组中,并将其添加到集合中,为新地图提供这些国家得分的总值

然后递归地对所有组执行该操作,最终得到一个组和一个总值

例如,如果您有:

score := map[string]int{
        "Canada": 7,
        "US": 2,
        "Germany": 3,
        "Korea": 4,
}
group1=
{[US:2][Germany:3]}
,总共5个

group1现在将以5分的“分数”回到初始集合中,因为它需要两个最低的分数。我们现在可以:

score := map[string]int{
        "Canada": 7,
        "Korea": 4,
        group1: `US:2 Germany:3` with a total of 5
}
如果这是集合中的最低分数,那么下一次迭代将是:

group2=
{[Korea:4][group1:5]}

 score := map[string]int{
            "Canada": 7,
            group2: `Korea:4 group1:5` with a total of 9
  }
等等,直到你只剩下一个。。我认为基本结构应该是这样的。但是,由于数据结构现在包含了一个
[string]int
映射以及这个新映射,因此我不确定这样做的正确方法

我意识到这不是一个一般性的问题,但是可以使用接口来解决这个问题吗?我是新手,所以建议会很有帮助

下面是一个例子来进一步说明我的意思:

您的问题可以通过一个简单的方法“轻松”解决

主程序包
进口(
“容器/堆”
“fmt”
)
//有分数的东西
类型可记分接口{
梯梁
分数()整数
}
//一个国家有名字和分数
类型国家结构{
名称字符串
分数整数
}
//国家实施计分制
func(c国家)分数()int{
返回c.score
}
// ... 和fmt.Stringer
func(c国家)字符串()字符串{
返回fmt.Sprintf(“%s[%d]”,c.name,c.score)
}
//一支球队由两名得分手组成,并有自己的得分
类型团队结构{
第一队,第二队得分
分数整数
}
//球队得分
func(t团队)分数()int{
返回t.score
}
// ... 和fmt.Stringer
func(t Team)String()字符串{
返回fmt.Sprintf((%s+%s)”,t.team1.String(),t.team2.String()
}
//堆将使用计分表的一部分实现
类型TeamHeap[]可评分
//TeamHeap实现heap.Interface
func(th TeamHeap)Len()int{
返回len(th)
}
func(th TeamHeap)减去(i,j int)bool{
返回th[i].Score()1{
t1:=heap.Pop(团队)。(可得分)
t2:=堆。Pop(团队)。(可得分)
Push(团队,团队{t1,t2,t1.Score()+t2.Score()})
}
//打印我们现在在堆中的团队
对于团队。Len()>0{
t:=heap.Pop(团队)。(团队)
fmt.Println(t)
}
}
你可以在运动场上找到。

package main
package main

import (
    "container/heap"
    "fmt"
)

//Recursive data structure may looks something like
type Group struct {
    Score   int
    Left    *Group
    Right   *Group
    Country string
}

//You can use slice to hold them organized in tree
type GrHeap []Group

//To implement your logic you can use stdlib/container/heap Heap interface
//you must implement Heap interface for your slice
func (h GrHeap) Len() int           { return len(h) }
func (h GrHeap) Less(i, j int) bool { return h[i].Score < h[j].Score }
func (h GrHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *GrHeap) Push(x interface{}) {
    // Push and Pop use pointer receivers because they modify the slice's length,
    // not just its contents.
    *h = append(*h, x.(Group))
}

func (h *GrHeap) Pop() interface{} {
    old := *h
    n := len(old)
    x := old[n-1]
    *h = old[0 : n-1]
    return x
}

func main() {
    //you most likely already have a map
    //anyway it will be handy to keep it for convenient access to individual country
    score := map[string]int{
        "Canada":  7,
        "US":      2,
        "Germany": 3,
        "Korea":   4,
    }
    //here we allocate heap
    gr := make(GrHeap, 0)
    //populate it from map
    for k, v := range score {
        g := Group{v, nil, nil, k}
        gr = append(gr, g)
    }
    //and initialize
    heap.Init(&gr)
    //and here we use heap magic to implement your logic
    for len(gr) > 2 {
        l := heap.Pop(&gr).(Group)
        r := heap.Pop(&gr).(Group)
        ng := Group{l.Score + r.Score, &l, &r, ""}
        heap.Push(&gr, ng)
    }
    fmt.Println(gr)
    fmt.Println(gr[1].Left)
    fmt.Println(gr[1].Right.Left)
//and you can see it works https://play.golang.org/p/gugJxJb7rr
}
进口( “容器/堆” “fmt” ) //递归数据结构可能看起来像 类型组结构{ 分数整数 左*组 右*组 国弦 } //可以使用“切片”将它们组织在树中 类型GrHeap[]组 //要实现逻辑,可以使用stdlib/container/heap接口 //必须为切片实现堆接口 func(h GrHeap)Len()int{return Len(h)} func(h GrHeap)Less(i,j int)bool{返回h[i]。分数2{ l:=heap.Pop(&gr)。(组) r:=heap.Pop(&gr)。(组) ng:=组{l.Score+r.Score,&l,&r,“} heap.Push(&gr,ng) } fmt.Println(gr) fmt.Println(组[1]。左) fmt.Println(gr[1]。右。左) //你可以看到它是有效的https://play.golang.org/p/gugJxJb7rr }
您可以尝试使用
类型断言
映射[string]接口{}
这是演示

package main

import "fmt"

const total = "total"


func GetValue(i interface{}) int {
    value, ok := i.(int)
    if ok {
        return value
    }
    return i.(map[string]interface{})[total].(int)
}

func main() {
    score := map[string]interface{}{
        "Canada":  7,
        "US":      2,
        "Germany": 3,
        "Korea":   4,
    }
    groupCount := 0

    for len(score) > 2 {
        var (
            firstMin  = math.MaxInt32
            secondMin = math.MaxInt32
            firstKey  = ""
            secondKey = ""
        )
        for k, v := range score {
            iv := GetValue(v)
            if iv < firstMin {
                secondMin = firstMin
                secondKey = firstKey
                firstMin = iv
                firstKey = k
                continue
            }
            if iv < secondMin {
                secondMin = iv
                secondKey = k
                continue
            }

        }
        groupCount++

        score[fmt.Sprintf("Group%d", groupCount)] = map[string]interface{}{
            firstKey:  score[firstKey],
            secondKey: score[secondKey],
            total:     GetValue(score[firstKey])+ GetValue(score[secondKey]),
        }
        delete(score, firstKey)
        delete(score, secondKey)
    }
    fmt.Println(score)
}
主程序包
输入“fmt”
const total=“总计”
func GetValue(i接口{})int{
值,ok:=i(int)
如果可以的话{
返回值
}
返回i.(映射[字符串]接口{})[总计](int)
}
func main(){
分数:=映射[字符串]接口{}{
“加拿大”:7,
"美国":二,,
“德国”:3,
“韩国”:4,
}
组计数:=0
对于len(分数)>2{
变量(
firstMin=math.MaxInt32
package main

import "fmt"

const total = "total"


func GetValue(i interface{}) int {
    value, ok := i.(int)
    if ok {
        return value
    }
    return i.(map[string]interface{})[total].(int)
}

func main() {
    score := map[string]interface{}{
        "Canada":  7,
        "US":      2,
        "Germany": 3,
        "Korea":   4,
    }
    groupCount := 0

    for len(score) > 2 {
        var (
            firstMin  = math.MaxInt32
            secondMin = math.MaxInt32
            firstKey  = ""
            secondKey = ""
        )
        for k, v := range score {
            iv := GetValue(v)
            if iv < firstMin {
                secondMin = firstMin
                secondKey = firstKey
                firstMin = iv
                firstKey = k
                continue
            }
            if iv < secondMin {
                secondMin = iv
                secondKey = k
                continue
            }

        }
        groupCount++

        score[fmt.Sprintf("Group%d", groupCount)] = map[string]interface{}{
            firstKey:  score[firstKey],
            secondKey: score[secondKey],
            total:     GetValue(score[firstKey])+ GetValue(score[secondKey]),
        }
        delete(score, firstKey)
        delete(score, secondKey)
    }
    fmt.Println(score)
}