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