es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Permutaciones de números en Golang, la recursión no funciona.

Aquí está el código:

package main

import "fmt"

func anon(n []int, sl []int, result [][]int) {
    if len(n) == 0 {
        result = append(result, sl)
        fmt.Printf("resultado %v\n", result)
        return
    }
    for i , _ := range n {
        fmt.Printf("n %v\n", n)
        sl = append(sl, n[i])
        ab := append(n[:i], n[i+1:]...)
        fmt.Printf("i %v --- ab %v, sl %v, result %v ---\n",i, ab,sl,result )

        anon(ab, sl , result)
    }
}

func permute(nums []int) [][]int {
    var sl1 = []int{}
    var result = [][]int{}
    anon(nums, sl1, result)
    return result
}

func main() {
  sl2 := []int{1,2}
  permute(sl2)
}

Espero ‘resultado’ como [[1,2], [2,1]]. Sin embargo, al ver la siguiente salida del código ejecutado:

 n [1 2]
i 0 --- ab [2], sl [1], result [] ---
 n [2]
i 0 --- ab [], sl [1 2], result [] ---
resultado [[1 2]]

Veamos que para (en negrita) i=1, tengo ab[2], sl[1 2], result[] y n[2,2]. No puedo hacerlo funcionar con Golang. Algo similar funciona bien con Python.

Gracias por responder.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Según el código proporcionado, hay algunos problemas a señalar que podrían dar lugar a resultados inesperados:

    • La función anon debería devolver la versión modificada de la lista result en lugar de simplemente agregar valores a ella. Esto se debe a que las listas en Go se pasan por valor, por lo que cuando la lista result se modifica dentro de anon, no refleja los cambios fuera de la función.
    • Dado que la lista result se modifica a lo largo de la recursión, es mejor utilizar un puntero a ella para que las modificaciones se realicen en la misma lista subyacente. Para hacer esto, la función anon debería recibir un puntero result *[][]int en lugar de una lista result [][]int.

    • En la función anon, cuando se agrega n[i] a sl, estamos modificando el mismo arreglo subyacente que n, ya que las listas en Go son solo vistas de arreglos de respaldo. Esto puede llevar a un comportamiento inesperado, como tener valores duplicados en la lista sl. Para evitar esto, debemos hacer una copia de la lista sl utilizando la función append.

    Aquí tienes una versión actualizada del código que aborda estos problemas:

    package main
    
    import "fmt"
    
    func anon(n []int, sl []int, result *[][]int) {
        if len(n) == 0 {
            *result = append(*result, append([]int{}, sl...))
            fmt.Printf("result %v\n", *result)
            return
        }
        for i, _ := range n {
            fmt.Printf("n %v\n", n)
            sl = append(sl, n[i])
            ab := append(n[:i], n[i+1:]...)
            fmt.Printf("i %v ---ab %v, sl %v, result %v ---\n", i, ab, sl, *result)
    
            anon(ab, sl, result)
            sl = sl[:len(sl)-1] // eliminar el último elemento (retroceder)
        }
    }
    
    func permute(nums []int) [][]int {
        var sl1 = []int{}
        var result = [][]int{}
        anon(nums, sl1, &result)
        return result
    }
    
    func main() {
        sl2 := []int{1, 2}
        fmt.Println(permute(sl2))
    }
    

    Esta versión del código debería producir el resultado [[1 2] [2 1]]. Nota que agregué una llamada a fmt.Println en main para imprimir el resultado de la función permute, y que agregué un paso de “retroceso” para eliminar el último elemento de la lista sl, de modo que no acumulemos valores entre diferentes ramas recursivas.

Comments are closed.