亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

golang組合生成出錯

golang組合生成出錯

Go
神不在的星期二 2023-06-12 12:58:29
我正在處理一個編程問題給定兩個整數 n 和 k,返回 1 ... n 中 k 個數字的所有可能組合。輸入 n = 5,k = 4,輸出應為 [[1,2,3,4],[1,2,3,5],[1,2,4,5],[1,3 ,4,5],[2,3,4,5]],下面是我的golang方案func combine(n int, k int) [][]int {    result := [][]int{}    comb := []int{}    subcom(0, k, n, &comb, &result)    return result}func subcom(s, k, n int, comb *[]int, result *[][]int) {    if k > 0 {        for i := s + 1; i <= n-k+1; i++ {            c := append(*comb, i)            subcom(i, k-1, n, &c, result)        }    } else {        *result = append(*result, *comb)    }}我認為我的解決方案是正確的,但它返回 [[1 2 3 5] [1 2 3 5] [1 2 4 5] [1 3 4 5] [2 3 4 5]]。調試后發現result slice一開始添加了[1 2 3 4],后來改成了[1 2 3 5],導致重復了兩個[1 2 3 5]。但我不知道這里出了什么問題。
查看完整描述

1 回答

?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

這是使用append.

當您的代碼運行時c:=append(*comb,i),它會嘗試首先使用底層數組中分配的內存來添加一個新項,并且僅在失敗時才創建一個新切片。這就是改變的原因[1 2 3 4]——[1 2 3 5]因為它們共享相同的底層內存。

要解決此問題,請在要附加到結果時復制:

now := make([]int,len(*comb))
copy(now,*comb)
*result = append(*result,now)

或者使用復制的快捷方式:

*result = append(*result, append([]int{},*comb...))

更新:

要理解我所說的底層內存的意思,應該理解 Go 切片的內部模型。

在 Go 中,一個 slice 有一個數據結構,可以SliceHeader通過reflectpackage 訪問它,它是你使用和獲取地址時所引用的unsafe.Sizeof

照顧SliceHeader三個要素:LenCapPtr。前兩個是微不足道的:它們是什么len(),cap()是為了什么。最后一個是uintptr指向切片包含的數據的內存。

當您淺拷貝一個切片時,SliceHeader會創建一個新的但內容相同的切片,包括Ptr. 所以底層內存不是復制的,而是共享的。


查看完整回答
反對 回復 2023-06-12
  • 1 回答
  • 0 關注
  • 174 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號