johnson
johnson

Reputation: 388

Go slice element replaced by last element

My problem is the answer should has [1 1 2 2], but it got [1 1 2 3]. I debuged this code, found that in that loop, [1 1 2 2] was appended to the array firstly, but it changed to [1 1 2 3] in next loop. I don't understand why, the log which started with 'D', the elements in this array changed in next loop. Here is my code: https://play.golang.org/p/X_CU8GlMOqf

package main

import (
    "fmt"
)

func main() {
    nums := []int{1, 1, 2, 2, 3}
    result := subsetsWithDup(nums)
    fmt.Println(result)
}

func subsetsWithDup(nums []int) [][]int {
    result := [][]int{{}, nums}
    for i := 0; i < len(nums); i++ {
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        for j := 1; j < len(nums); j++ {
            result = append(result, dsf(nums, []int{nums[i]}, i+1, j)...)
        }
    }
    return result
}

func dsf(nums []int, set []int, start int, length int) [][]int {
    result := [][]int{}
    if len(set) == length {
        return append(result, set)
    }
    for i := start; i < len(nums); i++ {
        if i != start && nums[i] == nums[i-1] {
            continue
        }
        if len(set) == 3 {
            fmt.Printf("A %v %p\n", result, &result)
        }
        tmp := set[:]
        tmp = append(tmp, nums[i])
        if len(set) == 3 {
            fmt.Printf("B %v %p %v %p\n", tmp, &tmp, result, &result)
        }
        result = append(result, dsf(nums, tmp, i+1, length)...)
        if len(tmp) == 4 {
            fmt.Printf("C %v %p %v %p\n", tmp, &tmp, result, &result)
            for _, r := range result {
                fmt.Printf("D %v %p\n", r, &r)
            }
        }
    }
    return result
}
A [] 0xc000004960
B [1 1 2 2] 0xc0000049c0 [] 0xc000004960
C [1 1 2 2] 0xc0000049c0 [[1 1 2 2]] 0xc000004960
D [1 1 2 2] 0xc000004ae0
A [[1 1 2 2]] 0xc000004960
B [1 1 2 3] 0xc000004b60 [[1 1 2 3]] 0xc000004960
C [1 1 2 3] 0xc000004b60 [[1 1 2 3] [1 1 2 3]] 0xc000004960
D [1 1 2 3] 0xc000004ca0
D [1 1 2 3] 0xc000004ca0
A [] 0xc000004da0
B [1 2 2 3] 0xc000004de0 [] 0xc000004da0
C [1 2 2 3] 0xc000004de0 [[1 2 2 3]] 0xc000004da0
D [1 2 2 3] 0xc000004f00

Upvotes: 0

Views: 227

Answers (1)

torek
torek

Reputation: 487885

You are trying to copy a slice with:

tmp := set[:]

This does not copy the slice, it re-uses the original slice. It has the same effect as tmp := set. You can use:

tmp := append([]int(nil), set...)

if you like. Here is your program with this change, and all the extra debug commented out.

Upvotes: 1

Related Questions