La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

LISP I.

Presentaciones similares


Presentación del tema: "LISP I."— Transcripción de la presentación:

1 LISP I

2 Programación recursiva frente a iterativa
Características de la programación recursiva: Implementación intuitiva y elegante. La traducción de la solución recursiva de un problema (caso base y caso recursivo) a código Lisp es prácticamente inmediata. Útil para optimizar cálculos. Las estructuras de datos en Lisp hacen un uso implíctito de los punteros, como en las listas: NIL ó Un cons cuyo cdr es, a su vez, una lista Útil cuando hay varios niveles de anidamiento. La solución para un nivel es válida para el resto. Formas de hacer versión iterativa: Con mapcar Con bucles (dolist, dotimes, etc. Desaconsejado).

3 Ejemplos de recursividad, (1)
Ejemplo del cálculo de la potencia de un número optimizada > (defun potencia (x n) ;; “Optimizacion calculo potencia" (cond ((= n 0) 1) ((evenp n) (expt (potencia x (/ n 2)) 2) ) (t (* x (potencia x (- n 1)))))) > (potencia 2 3) 8 La interpretación y comprensión del código es compleja. Por ello es importante llegar a un compromiso entre la claridad de la programación y la eficiencia en la misma.

4 Ejemplos de recursividad, (2)
Contar los átomos de cualquier expresión LISP: > (cuenta-atomos '(a (b c) ((d e) f))) 6 > (defun cuenta-atomos (expr) (cond ((null expr) 0) ((atom expr) 1) (t (+ (cuenta-atomos (first expr)) (cuenta-atomos (rest expr))))))

5 Ejemplos de recursividad, (3)
Aplanar una lista: (aplana ‘(a (b c) ((d e) f))) >>> (A B C D E F) > (defun aplana (lista) (cond ((null lista) NIL) ((atom (first lista)) (cons (first lista) (aplana (rest lista)))) (t (append (aplana (first lista)) (aplana (rest lista))))))

6 Ejemplos de recursividad, (4)
Número de sublistas de una lista (número de veces que se abre paréntesis, menos 1): (sublistas ‘(a (b c) ((d e) f))) >>> 3 > (defun sublistas (expresion) (cond ((or (null expresion) (atom expresion)) 0) (t (+ (if (atom (first expresion)) 0 1) (sublistas (first expresion)) (sublistas (rest expresion))))))

7 Ejemplos de recursividad, (5)
Producto escalar: (producto '(2 3) '(4 5)) >>> 23 2 x x 5 = 23 Versiones válidas: Versión recursiva: > (defun producto (vector1 vector2) (if (or (null vector1) (null vector2)) (+ (* (first vector1) (first vector2)) (producto (rest vector1) (rest vector2))))) Versión con mapcar >(defun producto (vector1 vector2) (apply #'+ (mapcar #'* vector1 vector2)))

8 Ejemplos de recursividad, (6)
Versión no válida del producto escalar: Versión iterativa (no recomendable): > (defun producto (vector1 vector2) (let ((suma 0)) (dotimes (i (length vector1)) (setf suma (+ suma (* (nth i vector1) (nth i vector2))))) suma))

9 Ejemplos de recursividad, (7)
> (defun profundidad-maxima (expresion) (cond ((null expresion) 0) ((atom expresion) 1) (t (+ 1 (apply #'max (mapcar #'profundidad-maxima expresion)))))) >>> PROFUNDIDAD-MAXIMA > (profundidad-maxima '(1)) >>>> 2 > (profundidad-maxima '((1 (2 (3))) 4)) >>>> 5

10 Repaso de operadores, (1)
Recordemos los siguientes operadores: COUNT-IF, FIND-IF, REMOVE-IF, REMOVE-IF-NOT, DELETE-IF, DELETE-IF-NOT COUNT / COUNT-IF Contar apariciones: (count <elemento> <lista> [:test <fun-igualdad>]) (count 2 ‘( )) 3 Contar los elementos que cumplen /no cumplen una condición de una lista (count-if[-not] <predicado><lista> (count-if ‘oddp ‘( ))

11 Repaso de operadores, (2)
FIND / FIND-IF Devuelve la primera aparición: (find <elemento> <lista> [:test <fun-igualdad>]) (find 2 ‘( )) 2 Devuelve el primer elemento que cumple/o no cumple el predicado (find-if[-not] <predicado><lista> (find-if ‘oddp '( )) 1 REMOVE / REMOVE-IF Borrar las apariciones de un elemento indicado (remove <elemento> <lista> (remove 2 ‘( )) ( ) Elimina los que cumple/o no cumple el predicado (remove-if[-not] <predicado><lista> (remove-if ‘oddp '( )) ( )

12 Ejemplos de recursividad, (8)
Objetivo: sin utilizar remove-if, conseguir la misma funcionalidad del operador: (quitar-si ‘evenp '( )) (1 3) Versiones válidas: Versión recursiva: (defun quitar-si (predicado lista) (cond ((null lista) nil) ((funcall predicado (car lista)) (quitar-si predicado (cdr lista))) (t (cons (car lista) (quitar-si predicado (cdr lista)))))) Versión con mapcar (delete NIL (mapcar #'(lambda (elemento) (when (not (funcall predicado elemento)) elemento)) lista)))

13 Ejemplos de recursividad, (9)
Recorriendo la lista con dolist: (defun QUITAR-SI (predicado lista) (let (listaaux) (dolist (i lista listaaux) (if (not (eval (list predicado i))) (setf listaaux (append listaaux (list i))) )

14 Ejemplos de recursividad, (10)
Versión errónea: Mal uso de mapcar. El hecho de que hagamos uso de mapcar no garantiza la corrección del código programado. (defun QUITAR-SI2 (predicado lista) (mapcar #’(lambda (elemento) (if (apply predicado (list elemento)) (remove elemento lista)) ) lista)) > (QUITAR-SI2 'evenp '( )) (NIL (1 3 4) NIL (1 2 3))


Descargar ppt "LISP I."

Presentaciones similares


Anuncios Google