所以这里有点奇怪。我的问题是,人们从运行我的代码得到的结果和我一样吗?如果是这样的话,这是我的代码的错误(我通常是python程序员),还是golang中的一个bug?
系统信息: Go版本(1.1.2) linux x64 (fedora 19)
代码的背景信息:我正在做的是找到从三角形顶部到底部的最高成本路线,这是从project_euler 18和67
The bug: I设置了一个名为pathA的变量,这是一个整数列表,加上从三角形中找到的新值的一个新int,例如,3,7,2附加8应该等于3,2,7,8,并且它等于!直到我设定了pathB。pathB的设置是正确的,但是突然之间,pathA与pathB的值相同。
tl;博士,当我设置另一个变量时,其中一个变量被覆盖。
我的代码如下:
package main
import (
"fmt"
)
func extendPaths(triangle, prePaths [][]int) [][]int {
nextLine := triangle[len(prePaths)]
fmt.Println("#####PrePaths: ", prePaths)
fmt.Println("#####nextLine: ", nextLine)
postPaths := [][]int{{}}
for i := 0; i < len(prePaths); i++ {
route := prePaths[i]
nextA := nextLine[i]
nextB := nextLine[i+1]
fmt.Println("Next A:", nextA, "Next B:", nextB, "\n")
pathA := append(route, nextA)
fmt.Println("pathA check#1:", pathA)
pathB := append(route, nextB)
fmt.Println("pathA check#2:", pathA, "\n")
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
postPaths = postPaths[1:]
prePaths = [][]int{postPaths[0]}
for i := 1; i < len(postPaths)-1; i += 2 {
if getSum(postPaths[i]) > getSum(postPaths[i+1]) {
prePaths = append(prePaths, postPaths[i])
} else {
prePaths = append(prePaths, postPaths[i+1])
}
}
prePaths = append(prePaths, postPaths[len(postPaths)-1])
return prePaths
}
func getSum(sumList []int) int {
total := 0
for i := 0; i < len(sumList); i++ {
total += sumList[i]
}
return total
}
func getPaths(triangle [][]int) {
prePaths := [][]int{{triangle[0][0]}}
for i := 0; i < len(triangle)-1; i++ {
prePaths = extendPaths(triangle, prePaths)
}
}
func main() {
triangle := [][]int{{3}, {7, 4}, {2, 4, 6}, {8, 5, 9, 3}}
getPaths(triangle)
}这给出了终端中的输出,如下所示:
#####PrePaths: [[3]]
#####nextLine: [7 4]
Next A: 7 Next B: 4
pathA check#1: [3 7]
pathA check#2: [3 7]
#####PrePaths: [[3 7] [3 4]]
#####nextLine: [2 4 6]
Next A: 2 Next B: 4
pathA check#1: [3 7 2]
pathA check#2: [3 7 2]
Next A: 4 Next B: 6
pathA check#1: [3 4 4]
pathA check#2: [3 4 4]
#####PrePaths: [[3 7 2] [3 7 4] [3 4 6]]
#####nextLine: [8 5 9 3]
Next A: 8 Next B: 5
pathA check#1: [3 7 2 8]
pathA check#2: [3 7 2 5]
Next A: 5 Next B: 9
pathA check#1: [3 7 4 5]
pathA check#2: [3 7 4 9]
Next A: 9 Next B: 3
pathA check#1: [3 4 6 9]
pathA check#2: [3 4 6 3]在这里您可以看到,在我设置pathA的最后4次中,它最初是正确设置的,但随后被pathB覆盖。
有人对此有任何想法吗?
编辑:
正如下面的评论所指出的,所需要的是制作新的切片并从原件复制数据。这是使用来自稍微修改过的http://blog.golang.org/go-slices-usage-and-internals的代码完成的:
func AppendInt(slice []int, data ...int) []int {
m := len(slice)
n := m + len(data)
if n > cap(slice) {
newSlice := make([]int, (n+1)*2)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:n]
copy(slice[m:n], data)
return slice
}我还修改了另一边的代码,在那里我创建了片pathA和pathB。这一情况改为:
for i := 0; i < len(prePaths); i++ {
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := AppendInt(prePaths[i], nextA)
pathB := AppendInt(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}EDIT2:
现在已经很早了,我在第一次编辑时犯了一个错误,我没有完全理解你的解决方案,经过一些黑客攻击,我终于做到了:
此代码不工作(pathA被覆盖):
for i := 0; i < len(prePaths); i++ {
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(prePaths[i], nextA)
pathB := append(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}此代码也不工作(pathA被覆盖):
for i := 0; i < len(prePaths); i++ {
newRoute := make([]int, len(prePaths[i]), (cap(prePaths[i])+1)*2)
copy(newRoute, prePaths[i])
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(newRoute, nextA)
pathB := append(newRoute, nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}但是,如果我将上面的两个场景混合到下面的代码中,它就能正常工作(pathA不会被覆盖):
for i := 0; i < len(prePaths); i++ {
newRoute := make([]int, len(prePaths[i]), (cap(prePaths[i])+1)*2)
copy(newRoute, prePaths[i])
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(newRoute, nextA)
pathB := append(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}因此,我的解决方案是复制数组,让它们都使用不同的数组。
发布于 2013-11-29 02:45:32
一个切片基本上是一个由三件事组成的结构:
运行以下代码时:
append(x, element)它做了以下工作:
在您的代码中,您有以下内容:
pathA := append(route, nextA)
pathB := append(route, nextB)现在这里有两种可能性:
len(route) == cap(route),并将分配一个新的支持数组,其中pathA和pathB具有独立的值。len(route) < cap(route),因此pathA和pathB最终共享了相同的支持数组。数组中的最后一个元素将是nextB,因为该操作是第二个运行的。在循环的前几次迭代中,第一种情况似乎是正确的,在此之后,您进入了第二种情况。您可以通过手动为您的路径之一创建一个副本来避免这种情况(用make()分配一个片,然后使用copy()复制旧数据)。
https://stackoverflow.com/questions/20277305
复制相似问题