为了账号安全,请及时绑定邮箱和手机立即绑定

附加字符串和数组的类似 Go 函数的行为与预期不符

附加字符串和数组的类似 Go 函数的行为与预期不符

Go
Qyouu 2021-11-22 18:33:35
我有两个 Go 函数:func permutation(prefix, str []int) {    n := len(str)    if n == 0 {        fmt.Println(prefix)    } else {        for i := 0; i < n; i++ {            permutation(                append(prefix, str[i]),                append(str[0:i], str[i+1:]...),            )        }    }}func perms(prefix, str string) {    n := len(str)    if n == 0 {        fmt.Println(prefix)    } else {        for i := 0; i < n; i++ {            perms(                prefix+string(str[i]),                string(str[0:i])+string(str[i+1:]),            )        }    }}第一个需要一个整数数组,第二个需要一个字符串。然后他们都计算数组或字符串的所有排列。我可以像这样运行它们:permutation([]int{}, []int{1, 2, 3})perms("", "123")他们的输出是不一样的:$ go run main.go[1 2 3][1 3 3][3 3 3][3 3 3][3 3 3][3 3 3]123132213231312321我想附加我缺少的数组有一些细微差别。我似乎无法弄清楚。知道发生了什么吗?
查看完整描述

1 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

虽然str1+str2确实返回了新的(与内存无关)字符串,append但不会以这种方式运行。例如append(str[0:i], str[i+1:]...)会破坏原来的内容str,覆盖str[i:]用str[i+1:]。这是因为str[0:i]将有能力追加str[i+1:]而不分配新的缓冲区。


解决方案是在每次迭代中创建一个全新的数组。至少对于str,因为append(prefix, str[i])是免疫这个问题的。例如:


for i := 0; i < n; i++ {

    var s []int

    s = append(s, str[0:i]...)

    s = append(s, str[i+1:]...)

    permutation(append(prefix, str[i]), s)

}

https://play.golang.org/p/lXwu39AA0V


有关切片和附加机制的更多信息:


http://blog.golang.org/go-slices-usage-and-internals


https://blog.golang.org/slices


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信