Go语言:动态向二维切片添加行的问题及去count优化需求
问题分析与解决方案
你的代码主要有两个核心问题:
count变量是值传递,递归中修改无效:每次调用combinations时,count都是传入值的副本,递归里的count++不会改变外层的count值,导致所有元素都被重复添加到matrix[0]里。- 切片引用特性的潜在风险:虽然你的代码里每次递归都用
concat := append(concat, rest[i])创建了新切片,但直接操作原matrix索引的方式不够稳妥,且手动维护计数容易出错。
下面是优化后的实现,既移除了count变量,又能正确生成你期望的二维切片:
优化后的代码实现
func combinations(sofar []int, rest []int, n int) [][]int { var result [][]int if n == 0 { // 复制sofar的副本存入结果,避免后续递归修改影响已保存的组合 combo := make([]int, len(sofar)) copy(combo, sofar) result = append(result, combo) return result } for i := range rest { // 创建sofar的独立副本,避免共享底层数组 concat := append(sofar[:0:0], sofar...) concat = append(concat, rest[i]) // 递归获取子组合,并合并到当前结果中 subResult := combinations(concat, rest[i+1:], n-1) result = append(result, subResult...) } return result } func factorial(x uint) uint { if x == 0 { return 1 } return x * factorial(x-1) } func triangleNumber() int { rest := []int{1,2,3,4} matrixSize := factorial(4)/(factorial(1)*factorial(3)) fmt.Println(matrixSize) matrix := combinations([]int{}, rest, 3) // 打印验证结果 for _, row := range matrix { fmt.Println(row) } return 0 } func main() { triangleNumber() }
关键改进说明
- 移除
count变量:让combinations函数直接返回结果切片,每次递归将子组合合并到上层结果中,完全不需要手动维护计数,逻辑更简洁可靠。 - 显式拷贝切片:
- 找到有效组合时,用
copy创建sofar的副本存入结果,彻底避免后续递归操作影响已保存的组合。 - 递归前用
append(sofar[:0:0], sofar...)创建sofar的独立副本,确保每次递归的concat都是独立切片,不会共享底层数组。
- 找到有效组合时,用
- 简化参数传递:不再需要传入
matrix和count,函数职责更单一,可读性和可维护性更强。
运行这段代码后,matrix的结果会和你期望的完全一致:
[1 2 3] [1 2 4] [1 3 4] [2 3 4]
内容的提问来源于stack exchange,提问作者maxflow
相关产品推荐
相关产品推荐

