मैं गो सीखने की कोशिश कर रहा हूं लेकिन मैं यह नहीं समझ सकता कि रिकर्सन कॉल स्टैक के अंत में यह कोड एक खाली टुकड़ा क्यों देता है, कोई मदद? साथ ही tmp डीबगर में रजिस्टर भी नहीं होता है।

func main() {
    input := [3]int{4, 6, 7}
    // expected [[6,7],[4,6,7],[4,6],[4,7]]
    fmt.Println(findSubsequences(input))
}

func findSubsequences(nums [3]int) [][]int {
    res := [][]int{}
    list := []int{}
    findSubsequence(res, list, nums, 0)
    return res
}

func findSubsequence(res [][]int, list []int, nums [3]int, id int) [][]int {
    if len(list) > 1 {
        tmp := make([]int, len(list))
        copy(tmp, list)
        res = append(res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // skip non-increase
        }
        if contains(unique, nums[i]) {
            continue // skip duplicate
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(res, list, nums, id+1)
        list = list[:len(list)-1]
    }
    return res
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}
go
3
John 25 अगस्त 2017, 14:00
2
आपको findSubsequence() का रिटर्न मान res को निर्दिष्ट करना होगा, उदा. res = findSubsequence(res, list, nums, 0), और जब पुनरावर्ती रूप से कॉल किया जाता है: res = findSubsequence(res, list, nums, id+1)। यह अकेले एल्गोरिथम को सही नहीं करेगा, लेकिन आपको परिणाम दिखाई देने लगेंगे।
 – 
icza
25 अगस्त 2017, 14:04
2
जावा पास-बाय-रेफरेंस का उपयोग करता है। गो पास-बाय-कॉपी (या पास-बाय-वैल्यू) का उपयोग करता है। देखें, और क्या गोलांग फंक्शन पैरामीटर को कॉपी-ऑन के रूप में पास किया गया है -लिखें?
 – 
icza
25 अगस्त 2017, 14:37
1
जब तक आप केवल स्लाइस के तत्वों को संशोधित करते हैं, लेकिन स्वयं स्लाइस हेडर को नहीं। एक स्लाइस में संलग्न करना स्लाइस हेडर को संशोधित करता है करता है (आप परिणाम को स्लाइस हेडर रखने वाले वेरिएबल को असाइन करते हैं जैसे unique = append(unique, nums[i])), इसलिए आपका स्टेटमेंट अब लागू नहीं होता है।
 – 
icza
25 अगस्त 2017, 15:01
1
append केवल उसी बैकिंग ऐरे को लिखेगा यदि वह काफ़ी बड़ा हो। यदि ऐसा नहीं है, तो सरणी की प्रतिलिपि बनाई जाएगी और लौटाए गए टुकड़े में एक नई बैकिंग सरणी होगी।
 – 
Art
25 अगस्त 2017, 15:01
1
एपेंड हेडर को संशोधित नहीं करता है (यह नहीं कर सकता है, क्योंकि यह इसकी केवल एक प्रति प्राप्त करता है), यह नया हेडर रिटर्न देता है, और रिटर्न वैल्यू का असाइनमेंट है हेडर को "संशोधित" क्या करता है।
 – 
icza
25 अगस्त 2017, 15:21

2 जवाब

सबसे बढ़िया उत्तर

टुकड़ा जोड़ने के लिए अपना कोड प्राप्त करने का यह समाधान है। GO में, यदि आप एक स्लाइस को बार-बार पास कर रहे हैं, तो आपको इसे संदर्भ द्वारा पास करना होगा। तो यह उस समस्या को हल करता है जो आप अनुभव कर रहे हैं कि आपका कोड खाली टुकड़ा कहां लौटाएगा। लेकिन आपका एल्गोरिदम उस परिणाम के लिए गलत लगता है जिसकी आप अपेक्षा कर रहे हैं।

func main() {
    input := [3]int{4, 6, 7}
    // expected [[6,7],[4,6,7],[4,6],[4,7]]
    fmt.Println(findSubsequences(input))
}

func findSubsequences(nums [3]int) [][]int {
    res := [][]int{}
    list := []int{}
    fmt.Print(nums)
    findSubsequence(&res, list, nums, 0)
    return res
}

func findSubsequence(res *[][]int, list []int, nums [3]int, id int) [][]int {
    var tmp []int
    if len(list) > 1 {
        tmp = make([]int, len(list))
        copy(tmp, list)
    fmt.Println(tmp)
        *res = append(*res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // skip non-increase
        }
        if contains(unique, nums[i]) {
            continue // skip duplicate
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(res, list, nums, id+1)
    list = list[:len(list)-1]

    }
    return *res
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e || a >e {
            return true
        }
    }
    return false
}
5
bashxx 27 अगस्त 2017, 01:07
ठीक है, एल्गोरिथम गलत हो सकता है, पुनरावर्ती रूप से संलग्न न होने के कारण इसे देखने के लिए नहीं मिला, लेकिन findSubsequence(res, list, nums, id+1) पुनरावर्ती कॉल findSubsequence(&res, list, nums, id+1) नहीं होना चाहिए? या शायद नहीं, क्योंकि उस बिंदु पर res एक सूचक है, लेकिन मैं अभी भी थोड़ा उलझन में हूं कि ऐसा क्यों होता है, मुझे गो पॉइंटर्स के बारे में पता है, लेकिन एक टुकड़ा एक बैकिंग सरणी का संदर्भ है, इसलिए एक सूचक ही है, मुझे लगता है कि संलग्न करें, बैकिंग सरणी को फिर से बनाता है, इससे कोई फर्क नहीं पड़ता, क्योंकि यह पूर्व-आवंटित विशाल रेस स्लाइस के साथ काम नहीं करता था।
 – 
John
27 अगस्त 2017, 10:13

मैंने अंत में वैश्विक चर का उपयोग किया, लेकिन अभी भी ठीक नहीं है, यह जावा से धीमी गति से काम करता है, वैसे भी यहां कोड है।

var res = [][]int{}
var list = []int{}

func findSubsequences(nums [3]int) [][]int {
    findSubsequence(nums, 0)
    return res
}

func findSubsequence(nums [3]int, id int) {
    if len(list) > 1 {
        tmp := make([]int, len(list))
        copy(tmp, list)
        res = append(res, tmp)
    }
    var unique []int
    for i := id; i < len(nums); i++ {
        if id > 0 && nums[i] < nums[id-1] {
            continue // skip non-increase
        }
        if contains(unique, nums[i]) {
            continue // skip duplicate
        }
        unique = append(unique, nums[i])
        list = append(list, nums[i])
        findSubsequence(nums, i+1)
        list = list[:len(list)-1]
    }
}

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}
-1
John 25 अगस्त 2017, 19:25