這裏有一個奇怪的位。我的問題是,像我一樣,人們運行代碼的結果是否相同?如果你這樣做,這是我的代碼(我通常是一個Python程序員)的錯誤,或者是golang中的錯誤?變量被覆蓋(bug?)
系統信息:轉到版本(1.1.2)的Linux的x64(Fedora的19)上的代碼
背景信息:我在做什麼是找到從一個頂部的最高性價比路線三角形的底部,這是來自project_euler 18和67
該缺陷:我設置一個名爲pathA變量,這是一個整數列表,以及用於新值新的int從三角形 例如發現3,7,2追加8應該等於3,2,7,8 ,它! ...直到我設定路徑B. 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。此更改爲:
EDIT2for 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)
}
:
它在這裏的早晨很早就和我平掉髮在我的第一個編輯錯誤,我沒有完全理解你的解決方案,後位黑客的我到底到了那裏:
此代碼不能正常工作(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)
}
但是,如果我混上面到下面的代碼中的2種情況,它工作正常(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)
}
所以,我的解決方案是製作陣列的副本,並讓它們都使用不同的陣列。
+1,正要寫出:) – nemo
非常感謝您對此的幫助。這解決了我所看到的問題。我已經更新了主帖,以反映所做的更改 – Gwynnie
請注意,如果您始終想要創建新的分片,則最好分配所需的確切長度,而不是像編輯時那樣將容量加倍題。擁有'cap> len'真的只有在你用「追加」或類似方法逐漸增長的情況下才有用。 –