You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:18:34