Неожиданное поведение при выполнении рекурсивного веселья c над срезом - PullRequest
0 голосов
/ 06 марта 2020

В Python я могу сделать рекурсию, такую ​​как:

def dfs(a, path):
    if len(a) == 0:
        print(path)
        return
    for i in range(len(a)):
        dfs(a[:i]+a[i+1:], path+str(a[i]))

if __name__ == "__main__":
    a = [10, 2]
    dfs(a, "")

Она выдаст:

102
210

Однако, если я сделаю аналогичную вещь в Go,

package main

import "fmt"

func dfs(ns []int, path string) {
    if len(ns) == 0 {
        fmt.Println(path)
        return
    }

    for i, v := range ns {
        nx := append(ns[:i], ns[i+1:]...)
        dfs(nx, fmt.Sprintf("%v%v", path, v))
    }
}

func main() {
    nums := []int{10, 2}
    dfs(nums, "")
}

Вывод будет:

102
22

Полагаю, такое поведение вызвано срезом, ссылающимся на массив подчеркивания на Go, но я не понимаю, как, и как это отладить.

Не могли бы вы указать мне проблему?

1 Ответ

1 голос
/ 06 марта 2020

Эта строка кода изменяет резервный массив из ns:

    nx := append(ns[:i], ns[i+1:]...)

Исправлено копированием элементов среза в новый резервный массив:

    nx := append(([]int)(nil), ns[:i]...) // copy
    nx = append(nx, ns[i+1:]...)

Запустите его на игровой площадке .

Вы также можете принудительно скопировать копию, используя полное выражение среза :

    nx := append(ns[0:i:i], ns[i+1:]...)

Выполнить это на детской площадке .

...