我想创建一个地图,用于存储从一个点到另一个点的路线,它们之间的距离将用作地图中的值。
type Route struct {
start string
finish string
}
m := make(map[Route]int)
v := Route{start: "A",
finish: "B"}
m[v] = 42
从A到B的距离等于从B到A的距离。
w := Route{start: "B",
finish: "A"}
如果再次将m[w]
推入地图,我怎样才能获得m[w] = 42
,因为v
和w
是相同的路线。
P.S换句话说,当在地图中使用Route
作为关键字时,当一个Route
等于另一个Route
时,是否可以覆盖规则?
答案 0 :(得分:2)
将map[Route]int
定义为用户定义的类型,例如RouteDistance
。
type RouteDistance map[Route]int
然后在该类型上定义Find
函数,以检查双向路由并返回距离。
func (rd RouteDistance) Find(r Route) (d int, ok bool) {
routeDistance := map[Route]int(rd)
d, ok = routeDistance[r]
if ok {
return
}
d, ok = routeDistance[Route{start: r.finish, finish: r.start}]
if ok {
return
}
return -1, false
}
仅使用单向路线和距离启动RouteDistance
。
rd := make(RouteDistance)
rd[Route{start: "A", finish: "B"}] = 42
获取路线的双向距离。
rd.Find(Route{start: "A", finish: "B"})
rd.Find(Route{start: "B", finish: "A"})
工作代码位于Playground
答案 1 :(得分:1)
使用Route
为地图编制索引,其中finish
和start
互换:
m[Route{start: w.finish, finish: w.start}]
如果要检查两个方向,请为其创建辅助函数:
var m = make(map[Route]int)
func dist(r Route) int {
if d, ok := m[r]; ok {
return d
}
return m[Route{start: r.finish, finish: r.start}]
}
请注意,如果地图中没有方向,dist()
将返回0
。如果您也想要返回此信息:
func dist(r Route) (d int, found bool) {
d, found = m[r]
if !found {
d, found = m[Route{start: r.finish, finish: r.start}]
}
return
}
在Go Playground上尝试。
答案 2 :(得分:1)
有几种方法可以在不增加额外值的情况下执行此操作。执行两次地图访问:
r := Route{
start: "B",
finish: "A",
}
d, ok := m[r]
if !ok {
r.start = "B"
r.finish = "A"
d, ok = m[r]
}
if !ok {
// value not found
}
或者对于每个地图商店和访问权限,请对start
和finish
:
func Put(start, finish string, d int) {
r := Route{start, finish}
if start > finish {
r.start = finish
r.finish = start
}
m[r] = d
}
func Get(r Route) int {
if r.start > r.finish {
r.start, r.finish = r.finish, r.start
}
m[r] = d
}