2011-04-20 22 views
7

¿Es posible hacerlo? Digamos que quiero obtener el último elemento de una lista, crearía una variable i = 0 y la incrementaría hasta que sea igual a la longitud. ¿Alguna idea? Un ejemplo sería muy apreciado.¿Cómo declarar una variable dentro de una función de esquema?

Gracias,

+1

¿Qué algoritmo tenía en mente para obtener el último elemento? –

+0

@larsmans: recorre la lista hasta que 'i' sea igual a la longitud? ¿Suena razonable en Scheme? – Chan

+0

suena como un desperdicio porque estás atravesando la lista dos veces; la primera vez para calcular la longitud. El algoritmo sería de tiempo lineal (no cuadrático como asume @ sepp2k), sino de dos pasos y no idiomático. –

Respuesta

11

Existen varias formas de declarar una variable; la más limpia es let:

(let ((x some-expr)) 
    ; code block that uses x 

Pero no es necesario esto para conseguir el último elemento de una lista. Sólo tiene que utilizar la recursividad:

(define (last xs) 
    (if (null? (cdr xs)) 
    (car xs) 
    (last (cdr xs)))) 

Nota: si lo desea, puede utilizar una variable para almacenar en caché cdr 's resultado:

(define (last xs) 
    (let ((tail (cdr xs))) 
    (if (null? tail) 
     (car xs) 
     (last tail)))) 
+0

Muchas gracias, muy buenas soluciones! Por cierto, estoy un poco confundido sobre la declaración if anterior. ¿La 'última cola' pertenece al' si' o es una declaración separada? ¿Cómo podemos diferenciar? – Chan

+1

@Chan: '(última cola)' es la parte else de la expresión 'if'. Se puede decir por los parens y por mi uso de sangrado. –

3

Sí, es posible definir variables locales en el esquema, ya sea usando let o define dentro de una función. Usando set!, también es posible reasignar una variable como usted se imagina.

Habiendo dicho eso, probablemente no deberías resolver tu problema de esta manera. En Scheme, generalmente es una buena práctica evitar set! cuando no lo necesite (y en este caso definitivamente no es necesario). Más iterar sobre una lista usando índices es usualmente una mala idea ya que las listas de esquema son listas enlazadas y como tal acceso aleatorio O (n) (haciendo que la función last funcione como desee O(n^2)).

De modo que una simple implementación recursiva sin índices sería más idiomática y más rápida de lo que planeas hacer y, como tal, preferible.

+1

Gracias. Mi problema es eliminar el último elemento de la lista. Podría revertir la lista, luego eliminar el primer elemento, pero parecía demasiado ineficiente. Pensar en Scheme es completamente extraño si se compara con otro lenguaje tradicional como C o C++. – Chan

+0

¿Hay alguna otra forma de redefinir una variable en Scheme, además de usar 'set!'? –

Cuestiones relacionadas