前两天在解扫地机器人算法的问题时, 遇到一个坑
部分代码如下:
- func move2(startPoint Point) [][]Point {
- allFootPrint := [][]Point{{startPoint}}
- for i := 0; i <N; i++ {
- allNewFootPrint := make([][]Point, 0)
- for len(allFootPrint)> 0 {
- curFootPrint := allFootPrint[len(allFootPrint)-1]
- allFootPrint = allFootPrint[:len(allFootPrint)-1]
- last := curFootPrint[len(curFootPrint)-1]
- for _, d := range directions {
- nextPoint := Point{last.X + d[0], last.Y + d[1]}
- if !inArray(nextPoint, curFootPrint) {
- // 必须复制一份数据出来, 否则会发生路径重复
- newCurFootPrint := make([]Point, len(curFootPrint))
- copy(newCurFootPrint, curFootPrint)
- allNewFootPrint = append(allNewFootPrint, append(newCurFootPrint, nextPoint))
- }
- }
- }
- allFootPrint = allNewFootPrint
- }
- return allFootPrint
- }
这处注释的地方非常关键, 如果不复制出来, 会导至 allNewFootPrint 中出现连续的两个相同路径, 并且不是所有的路径都出问题, 只会在一轮循环结束后, 新一轮循环开始时才会出现, 当时查了半天才查出问题.
现在把这个问题单独拎出来, 分享给大家.
- package main
- import "fmt"
- func main() {
- a := []int{1,2,3,4,5,6}
- x := a[:2]
- x = append(x, 9)
- fmt.Println(x)
- fmt.Println(a)
- }
输出:
- [1 2 9]
- [1 2 9 4 5 6]
上面的操作很简单, 就是从 a 切片里取出前 2 个, 然后再追加一个数字 9 进去.
结果我们发现 x 是正确的, 但 a 切片也随之发生了改动.
这说明 x 其实只是 a 切片的一个引用, 对 x 的任何改动, 都会影响到 a.
这简直是挖了个天大的坑, 机器人的问题也正是这里的问题.
只能 copy 出一个新的 slice 方能解决这个问题
- package main
- import "fmt"
- func main() {
- a := []int{1,2,3,4,5,6}
- c := make([]int, 2)
- copy(c, a[:2])
- c = append(c, 9)
- fmt.Println(c)
- fmt.Println(a)
- }
输出:
- [1 2 9]
- [1 2 3 4 5 6]
来源: http://www.bubuko.com/infodetail-3165685.html