首頁 > 後端開發 > Golang > 主體

為什麼這些元組沒有正確產生?

WBOY
發布: 2024-02-09 10:00:11
轉載
968 人瀏覽過

為什麼這些元組沒有正確產生?

php小編蘋果在寫程式碼時,常常會遇到一些問題,其中一個常見問題是元組產生不正確的情況。這可能是由於程式碼邏輯錯誤、資料類型不符或其他錯誤導致的。在解決這個問題之前,我們需要先仔細分析程式碼,找出可能的錯誤點,並逐一檢查。只有找到問題所在,才能進行相應的修復,確保元組正確生成,以確保程式碼的正常運作。

問題內容

我一直在從事一個項目,該項目要求我從一組(複數)數字生成特定長度的所有可能的元組。為此,我嘗試實作 Mathematica Tuples[] 命令的一個版本,但發現它沒有正確產生所有元組。

經過多次挫折,我發現當我的程式產生長度為 4 的元組時,它會添加重複項而不是新元素,從而導致任何更長長度的元組出現問題。我在網上查看是否有人有任何其他類似的問題,然後找到了一些其他程式碼來完成相同的任務,並注意到我的解決方案與他們的解決方案類似。我不知道自己哪裡出了問題。

經過更多的挫折後,我發現如果我將元素添加到清單中,一切都會正常工作,只有附加才是問題所在。我試圖找出我的原始程式碼有什麼問題,但一無所獲。

以下是我為示範該問題而寫的程式碼。我絕不是一個專業的編碼員,所以如果這不是完成這項任務的最慣用的方法,你必須原諒我。目前,我在實際程式碼中使用 tuplesByPrepend 函數,它運作得很好,我真的只是希望了解 tuplesByAppend 函數出了什麼問題。同樣,在我測試過的第三、第五、第八和任何其他級別上,它似乎都表現良好。如果需要的話,我可以提供有關我的作業系統和建置以及所有這些的更多資訊。

package main

import "fmt"

func tuplesByAppend[T any](list []T, depth int) [][]T {
    var l1 [][]T
    var l2 [][]T

    for _, v := range list {
        l1 = append(l1, []T{v})
    }

    for i := 1; i < depth; i++ {
        for _, u := range l1 {
            for _, v := range list {
                // Differs here
                next := append(u, v)
                // next is calculated properly, but added to l2 incorrectly at the fourth level only
                // at the fifth level it functions properly
                // fmt.Println(next)
                l2 = append(l2, next)
                // fmt.Println(l2)

                // it appears that at the fourth level it is writing over the previous entries
                // Printing here yields
                // [[1 1 1 1]]
                // [[1 1 1 2] [1 1 1 2]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 1]]
                // [[1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 2] [1 1 2 2]]
                // and so on.
            }
        }
        l1 = l2
        l2 = [][]T{}
    }

    return l1
}

func tuplesByPrepend[T any](list []T, depth int) [][]T {
    var l1 [][]T
    var l2 [][]T

    for _, v := range list {
        l1 = append(l1, []T{v})
    }

    for i := 1; i < depth; i++ {
        for _, u := range l1 {
            for _, v := range list {
                // Differs here
                next := append([]T{v}, u...)
                l2 = append(l2, next)
            }
        }
        l1 = l2
        l2 = [][]T{}
    }

    return l1
}

func main() {
    ourlist := []int{1, 2, 3}
    ourdepth := 4
    appended := tuplesByAppend(ourlist, ourdepth)
    prepended := tuplesByPrepend(ourlist, ourdepth)

    // We should expect this slice to start [1 1 1 1] [1 1 1 2] [1 1 1 3] [1 1 2 1] ...
    // In fact, it starts                   [1 1 1 3] [1 1 1 3] [1 1 1 3] [1 1 2 3]
    fmt.Println(appended)
    // This slice is as expected
    fmt.Println(prepended)
}
登入後複製

解決方法

在某些情況下,以下行無法按您的預期工作:

next := append(u, v)
登入後複製

此範例示範了發生的情況:

package main

import "fmt"

func main() {
    u := append([]int{1, 2}, 3)
    // The length is 3 but the capacity is 4.
    fmt.Printf("u %v\n  len: %d\n  cap: %d\n", u, len(u), cap(u))

    // Since u has enough capacity for the new element "4",
    // v1 will share the same underlying array.
    v1 := append(u, 4)
    fmt.Println("v1:", v1)

    // As what happened to v1, v2 will share the same underlying array too.
    // But the last element "4" in the underlying array is changed to "5".
    v2 := append(u, 5)
    fmt.Println("v2:", v2)

    // Since v1 uses the same underlying array, it sees the change in the last step.
    fmt.Println("v1:", v1)
}
登入後複製

要防止它共用底層數組,請將 next :=append(u, v) 替換為以下程式碼:

next := make([]T, len(u)+1)
copy(next, u)
next[len(u)] = v
登入後複製

請參閱 Go Slices:用法和內部原理以了解更多資訊。

以上是為什麼這些元組沒有正確產生?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!