递归地向切片追加元素不起作用。

huangapple go评论79阅读模式
英文:

Recursively append to slice not working

问题

我正在尝试学习Go语言,但是我无法理解为什么在递归调用栈的末尾,这段代码返回一个空切片。有什么帮助吗?另外,调试器中似乎连tmp都没有注册。

func main() {
    input := [3]int{4, 6, 7}
    // 期望结果为[[6,7],[4,6,7],[4,6],[4,7]]
    fmt.Println(findSubsequences(input))
}

func findSubsequences(nums [3]int) [][]int {
    res := [][]int{}
    list := []int{}
    findSubsequence(res, list, nums, 0)
    return res
}

func findSubsequence(res [][]int, list []int, nums [3]int, id int) [][]int {
    if len(list) > 1 {
        tmp := make([]int, len(list))
        copy(tmp, list)
        res = append(res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // 跳过非递增的数字
        }
        if contains(unique, nums[i]) {
            continue // 跳过重复的数字
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(res, list, nums, id+1)
        list = list[:len(list)-1]
    }
    return res
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

这段代码的目的是找到给定数组中的所有递增子序列。在findSubsequence函数中,如果list的长度大于1,它会将list的副本tmp添加到结果res中。然后,它遍历数组nums,将满足条件的数字添加到list中,并递归调用findSubsequence函数。在递归调用之后,它会将list的最后一个元素移除,以便继续遍历其他数字。

可能导致返回空切片的原因是res在递归调用中没有正确更新。在Go语言中,切片是引用类型,当切片作为参数传递给函数时,函数对切片的修改会影响到原始切片。然而,在递归调用中,res被重新分配了一个新的切片,而不是对原始切片进行修改。为了解决这个问题,你可以将res作为指针传递给findSubsequence函数,并在递归调用中更新它。

关于tmp在调试器中没有注册的问题,这可能是因为调试器的工作方式不同,它可能不会显示所有的临时变量。你可以尝试使用其他调试技术,如打印语句或日志记录,来查看tmp的值。

希望这些信息对你有帮助!如果还有其他问题,请随时提问。

英文:

I'm trying to learn Go but I can't figure it out why this code at the end of the recursion call stack returns an empty slice, any help? Also tmp doesn't even seem to register in the debugger.

func main() {
	input := [3]int{4, 6, 7}
	// expected [[6,7],[4,6,7],[4,6],[4,7]]
	fmt.Println(findSubsequences(input))
}

func findSubsequences(nums [3]int) [][]int {
	res := [][]int{}
	list := []int{}
	findSubsequence(res, list, nums, 0)
	return res
}

func findSubsequence(res [][]int, list []int, nums [3]int, id int) [][]int {
	if len(list) &gt; 1 {
		tmp := make([]int, len(list))
		copy(tmp, list)
		res = append(res, tmp)
	}
	var unique []int
	for i := id; i &lt; len(nums); i++ {
		if id &gt; 0 &amp;&amp; nums[i] &lt; nums[id-1] {
			continue // skip non-increase
		}
		if contains(unique, nums[i]) {
			continue // skip duplicate
		}
		unique = append(unique, nums[i])
		list = append(list, nums[i])
		findSubsequence(res, list, nums, id+1)
		list = list[:len(list)-1]
	}
	return res
}

func contains(s []int, e int) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

答案1

得分: 6

这是将你的代码修改为追加切片的解决方案。在Go语言中,如果你在递归中传递切片,你必须通过引用传递它。所以这解决了你遇到的代码返回空切片的问题。但是你的算法似乎对你期望的结果是不正确的。

func main() {
    input := [3]int{4, 6, 7}
    // 期望结果 [[6,7],[4,6,7],[4,6],[4,7]]
    fmt.Println(findSubsequences(input))
}

func findSubsequences(nums [3]int) [][]int {
    res := [][]int{}
    list := []int{}
    fmt.Print(nums)
    findSubsequence(&res, list, nums, 0)
    return res
}

func findSubsequence(res *[][]int, list []int, nums [3]int, id int) [][]int {
    var tmp []int
    if len(list) > 1 {
        tmp = make([]int, len(list))
        copy(tmp, list)
        fmt.Println(tmp)
        *res = append(*res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // 跳过非递增的数字
        }
        if contains(unique, nums[i]) {
            continue // 跳过重复的数字
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(res, list, nums, id+1)
        list = list[:len(list)-1]
    }
    return *res
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e || a > e {
            return true
        }
    }
    return false
}

希望对你有帮助!

英文:

This is the solution to get your code to append the slice. In GO, if you are recursively passing a slice, you must pass it by reference. So this solves the problem that you are experiencing where your code will return empty slice. But your algorithm seems incorrect for the result that you are expecting.

func main() {
input := [3]int{4, 6, 7}
// expected [[6,7],[4,6,7],[4,6],[4,7]]
fmt.Println(findSubsequences(input))
}
func findSubsequences(nums [3]int) [][]int {
res := [][]int{}
list := []int{}
fmt.Print(nums)
findSubsequence(&amp;res, list, nums, 0)
return res
}
func findSubsequence(res *[][]int, list []int, nums [3]int, id int) [][]int {
var tmp []int
if len(list) &gt; 1 {
tmp = make([]int, len(list))
copy(tmp, list)
fmt.Println(tmp)
*res = append(*res, tmp)
}
var unique []int
for i := id; i &lt; len(nums); i++ {
if id &gt; 0 &amp;&amp; nums[i] &lt; nums[id-1] {
continue // skip non-increase
}
if contains(unique, nums[i]) {
continue // skip duplicate
}
unique = append(unique, nums[i])
list = append(list, nums[i])
findSubsequence(res, list, nums, id+1)
list = list[:len(list)-1]
}
return *res
}
func contains(s []int, e int) bool {
for _, a := range s {
if a == e || a &gt;e {
return true
}
}
return false
}

答案2

得分: -2

我在最后使用了全局变量,但仍然不行,它比Java运行得慢,无论如何这是代码。

var res = [][]int{}
var list = []int{}

func findSubsequences(nums [3]int) [][]int {
    findSubsequence(nums, 0)
    return res
}

func findSubsequence(nums [3]int, id int) {
    if len(list) > 1 {
        tmp := make([]int, len(list))
        copy(tmp, list)
        res = append(res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // skip non-increase
        }
        if contains(unique, nums[i]) {
            continue // skip duplicate
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(nums, i+1)
        list = list[:len(list)-1]
    }
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

希望对你有帮助!

英文:

I used global variables in the end, but is still not OK, it works slower than Java, anyway here is the code.

var res = [][]int{}
var list = []int{}
func findSubsequences(nums [3]int) [][]int {
findSubsequence(nums, 0)
return res
}
func findSubsequence(nums [3]int, id int) {
if len(list) &gt; 1 {
tmp := make([]int, len(list))
copy(tmp, list)
res = append(res, tmp)
}
var unique []int
for i := id; i &lt; len(nums); i++ {
if id &gt; 0 &amp;&amp; nums[i] &lt; nums[id-1] {
continue // skip non-increase
}
if contains(unique, nums[i]) {
continue // skip duplicate
}
unique = append(unique, nums[i])
list = append(list, nums[i])
findSubsequence(nums, i+1)
list = list[:len(list)-1]
}
}
func contains(s []int, e int) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

huangapple
  • 本文由 发表于 2017年8月25日 19:00:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/45879903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定