Golang slice append exception - go
This is a leet code problem, and when I try to answer with the code blew:
package main
import "fmt"
func main() {
nums := []int{9, 0, 3, 5, 7}
fmt.Println(subsets(nums))
}
func subsets(nums []int) [][]int {
var result [][]int
result = append(result, []int{})
for _, v := range(nums) {
for _, rv := range(result) {
result = append(result, append(rv, v))
}
}
return result
}
Leetcode told me wrong answer:
Wrong Answer
Details
Input
[9,0,3,5,7]
Output
[[],[9],[0],[9,0],[3],[9,3],[0,3],[9,0,3],[5],[9,5],[0,5],[9,0,5],[3,5],[9,3,5],[0,3,5],[9,0,3,7],[7],[9,7],[0,7],[9,0,7],[3,7],[9,3,7],[0,3,7],[9,0,3,7],[5,7],[9,5,7],[0,5,7],[9,0,5,7],[3,5,7],[9,3,5,7],[0,3,5,7],[9,0,3,7,7]]
Expected
[[],[9],[0],[0,9],[3],[3,9],[0,3],[0,3,9],[5],[5,9],[0,5],[0,5,9],[3,5],[3,5,9],[0,3,5],[0,3,5,9],[7],[7,9],[0,7],[0,7,9],[3,7],[3,7,9],[0,3,7],[0,3,7,9],[5,7],[5,7,9],[0,5,7],[0,5,7,9],[3,5,7],[3,5,7,9],[0,3,5,7],[0,3,5,7,9]]
The output slice index 15, it should be [9,0,3,5] like the expected, but the result is [9,0,3,7].
So I try to run this code by go playgroud online,the answer is the same wrong, and then I run this code in goland with debug mode,I find when I make the slice append([9,0,3], 7), the output slice index 15 change at the same time.
My local go env: go version go1.17.6 windows/amd64
I'm just a beginner to golang, could anyone explain this situation?
Thank you very much.
ps: I try to use blew code to recover same issue, but I failed.
package main
import "fmt"
func main() {
a := [][]int{{}, {9}, {0}, {9, 0}, {3}, {9, 3}, {0, 3}, {9, 0, 3}, {5}, {9, 5}, {0, 5}, {9, 0, 5}, {3, 5}, {9, 3, 5}, {0, 3, 5}, {9, 0, 3, 5}}
i := 7
for _, v := range a {
// fmt.Println(a)
a = append(a, append(v, i))
// fmt.Println(a)
}
fmt.Println(a)
}
result:
[[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5] [7] [9 7] [0 7] [9 0 7] [3 7] [9 3 7] [0 3 7] [9 0 3 7] [5 7] [9 5 7] [0 5 7] [9 0 5 7] [3 5 7] [9 3 5 7] [0 3 5 7] [9 0 3 5 7]]
You are reusing the same backing array in some of your slices, because that's what append does if there's capacity remaining. A simple fix is to replace append(rv, v) with append(append([]int{}, rv...), v), creating an entirely new slice. An alternative is to force the append to allocate a fresh backing array by capping the slice to its current length: append(rv[:len(rv):len(rv)], v).
Playground link with working code: https://go.dev/play/p/Gc-yF5KQOAO
Related
Generate all combinations of slice - design of experiment in Go
I have the following levels in a design of experiment. levels := []int{0, 5, 10} // three levels The factors are as follows: factors := []int{6, 21, 7, 8, 32} // five factors The important thing is that there are Nf factors. Number of experiments is therefore: n := math.Pow(float64(3), float64(Nf)) // = 243 I need to generate all possible 243 combos as follows: 1: {0, 0, 0, 0, 0} 2: {0, 0, 0, 0, 5} 3: {0, 0, 0, 0, 10} 4: {0, 0, 0, 5, 0} 5: {0, 0, 0, 5, 5} 6: {0, 0, 0, 5, 10} 7: {0, 0, 0, 10, 0} ... 243: {10, 10, 10, 10, 10} How do I go about doing this in a generic function in Go, knowing that the number of factors can be variable?
I have a solution (Cartesian product) that works, using the Gonum package. Here below the code: import ( "fmt" "gonum.org/v1/gonum/stat/combin" ) factors := []int{3, 3, 3, 3, 3} // three levels for each factor. list := combin.Cartesian(factors) for i, v := range list { fmt.Println(i, v) } which returns the index for each level: 0 [0 0 0 0 0] 1 [0 0 0 0 1] ... 240 [2 2 2 2 0] 241 [2 2 2 2 1] 242 [2 2 2 2 2] So if someone has a better way of doing this using the standard lib, please let me know.
When the slice element is removed, the original slice is broken
package main import ( "fmt" ) func main() { // test data var a = [][]int{ []int{1,2}, []int{3,4}, []int{5,6}, []int{7,8}, } for i := range a { fmt.Println(a) // print out _ = append(a[:i], a[i+1:]...) // remove element } } expected result [[1 2] [3 4] [5 6] [7 8]] [[1 2] [3 4] [5 6] [7 8]] [[1 2] [3 4] [5 6] [7 8]] [[1 2] [3 4] [5 6] [7 8]] actual result [[1 2] [3 4] [5 6] [7 8]] [[3 4] [5 6] [7 8] [7 8]] [[3 4] [7 8] [7 8] [7 8]] [[3 4] [7 8] [7 8] [7 8]] https://play.golang.org/p/KahcX1MmDHO why does this result? the original slice is broken. :(
When you re-slice you don't change the underlying array. So the first time through your loop (append(a[:0], a[1:]...)) you create a[:0] which is a slice of len 0 (cap 4) pointing to the element 0 and a[1:] is a slice of len 3 (cap 3) pointing to element 1. As #icza pointed out using append() in this way just moved the underlying array elements around. For each loop iteration this happens: 0: elements 1-3 are moved to places 0-2 1: elements 2-3 are moved to places 1-2 2: element 3 is moved to place 2 3: nothing is moved since a[4:] has zero length This gives the changed values that you see. BTW Please post the simplest code which shows the problem. The nested slice is irrelevant. func main() { var a = []int{1,2,3,4} for i := range a { fmt.Println(a) _ = append(a[:i], a[i+1:]...) } }
Golang - How to remove a row from a matrix?
So I have this 2D slice, for example: s := [][]int{ {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, } fmt.Println(s) //Outputs: [[0 1 2 3] [4 5 6 7] [8 9 10 11]] How can I remove a full row from this 2D slice, so that the result would look like this if I decide to remove the middle row: [[0 1 2 3] [8 9 10 11]]
The formula to delete row at index i is: s = append(s[:i], s[i+1:]) Here's a working example: package main import ( "fmt" ) func main() { s := [][]int{ {0, 1, 2, 3}, {4, 5, 6, 7}, // This will be removed. {8, 9, 10, 11}, } // Delete row at index 1 without modifying original slice by // appending to a new slice. s2 := append([][]int{}, append(s[:1], s[2:]...)...) fmt.Println(s2) // Delete row at index 1. Original slice is modified. s = append(s[:1], s[2:]...) fmt.Println(s) } Try it in the Go playground. I recommend you to read Go Slice Tricks. Some of the tricks can be applied to multidimensional slices as well.
You can try the following: i := 1 s = append(s[:i],s[i+1:]...) You can try the working code in the Golang playground Another alternative way is to use the following: i := 1 s = s[:i+copy(s[i:], s[i+1:])] Golang Playground
How to separate numbers from a slice?
Let's say I have a list with 10 numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] I would like my program to slice every 3 numbers, for example: [1,2,3] [4,5,6] [7,8,9] How can I do it? Grateful
For example, with n = 3, package main import "fmt" func main() { list := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for a, n := list, 3; len(a) >= n; a = a[n:] { slice := a[:n] fmt.Println(slice) } } Output: [1 2 3] [4 5 6] [7 8 9]
you could make a something like this (sorry for pseudo code) array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] while (array){ list = "" for($i=1;$i -le 3;$i++){ list.add = array[$i] remove from array the array[$i] } your list now here (list) } you could ask the first 3 values and after that you remove it
Numpy sorting help
In Numpy, how do I create an array of indices which can be used return the values of the source array in sorted order? eg: Source: [[4 2 6 7] [1 4 8 9] [3 1 0 3]] Indices: [10 4 9 1 8 11 0 5 2 3 6 7]
Take a look at numpy.argsort - it will return the indices that would sort your array. You can also specifiy the axis along which to sort. Try: a = numpy.asarray([[4, 2, 6, 7], [1, 4, 8, 9], [3, 1, 0, 3]]) numpy.argsort(a.flat) >> array([10, 4, 9, 1, 8, 11, 0, 5, 2, 3, 6, 7])
The answer's in the manual: src = [[ ... ]] ravel_src = np.ravel(src) indices = np.argsort(ra)