本文共 5564 字,大约阅读时间需要 18 分钟。
L-99: Ninety-Nine Lisp ProblemsBased on a Prolog problem list by werner.hett@hti.bfh.chWorking with listsP01 (*) Find the last box of a list. Example: * (my-last '(a b c d)) (D)CL-USER> (defun last-l (l) (if (null (cdr l)) l (last-l (cdr l))))LAST-LCL-USER> (last-l '(a b c( c d )))(C)CL-USER> (last-l '(a b c( c d )))((C D))P02 (*) Find the last but one box of a list. Example: * (my-but-last '(a b c d)) (C D)CL-USER> (defun my-but-l (l) (if (= 1 (length (cdr l))) l (my-but-l (cdr l))))STYLE-WARNING: redefining COMMON-LISP-USER::MY-BUT-L in DEFUNMY-BUT-LCL-USER> my-but-l '( a b c d ( x y)))(C D)CL-USER> (my-but-l '( a b c d ( x y)))(D (X Y))CL-USER> CL-USER>(defun my-but-l (l) (if (null (cdr (cdr l))) l (my-but-l (cdr l))))CL-USER> (my-but-l '( a b c d ( x y)))(D (X Y))CL-USER> (my-but-l '( a b c d ))(C D)P03 (*) Find the K'th element of a list. The first element in the list is number 1. Example: * (element-at '(a b c d e) 3) CCL-USER> (defun element-n (l n) (if (<= n (length l)) (nth (1- n) l) nil))ELEMENT-NCL-USER> (elment-n '(a b c d) 3)CCL-USER> (elment-n '(a b (c d e) d) 3)(C D E)CL-USER> (element-n '(a b c) 3)NILCL-USER> (element-n '(a b c) 3)CCL-USER> P04 (*) Find the number of elements of a list.提示通过构建hash表来去重,性能一般。(defun element-of-l (l) (let ((h (make-hash-table ))) (loop for i in l do (setf (gethash i h) i)) (hash-table-count h)))ELEMENT-OF-LCL-USER> (element-of-l '(a b c d a e f a))6CL-USER> (element-of-l '(a))1CL-USER> (element-of-l '(a b c d a e f a (s q ( s q))))7CL-USER> ; No valueCL-USER> (element-of-l '(a b c d a e f a (s q ( s q)) (s q) ))8CL-USER> P05 (*) Reverse a list.CL-USER> (reverse '(a b c d (e f) ))(D C B A)CL-USER> (reverse '(a b c d (e f) ))((E F) D C B A)CL-USER> P06 (*) Find out whether a list is a palindrome. A palindrome can be read forward or backward; e.g. (x a m a x).(defun palidrome?(l) (let ( (rl (reverse l)) (s nil)) (setq s (multiple-value-list ( loop for i in rl do (mapcar #'equal rl l)))) (loop for k in s do (if (not (eql k t) ) (return nil))) t)) STYLE-WARNING: redefining COMMON-LISP-USER::PALIDROME? in DEFUNPALIDROME?CL-USER> (palidrome? '(a b c (x y) c b a))TCL-USER> (palidrome? '(aa bb cc (x y) cc bb aa))TCL-USER> (palidrome? '(aa bb cc (x y) cc bb aa))TCL-USER> P07 (**) Flatten a nested list structure. Transform. a list, possibly holding lists as elements into a `flat' list by replacing each list with its elements (recursively). Example: * (my-flatten '(a (b (c d) e))) (A B C D E) Hint: Use the predefined functions list and append.P08 (**) Eliminate consecutive duplicates of list elements. If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed. Example: * (compress '(a a a a b c c a a d e e e e)) (A B C A D E)CL-USER> (defun get-element (lst) (if (null lst ) nil (let ((rl (list(car lst) )) (first (car lst))) (loop for i in lst do (if (not (equal first i )) (progn (setf rl (append rl (list i))) (setf first i )))) rl)))STYLE-WARNING: redefining COMMON-LISP-USER::GET-ELEMENT in DEFUNGET-ELEMENTCL-USER> (get-element nil)NILCL-USER> (get-element '(a a a a b c c a a d e e e e))(A B C A D E)CL-USER> (get-element '(a a a a b c c a a (x y) (x y) (x y y) d e e e e))(A B C A (X Y) (X Y Y) D E)CL-USER> P09 (**) Pack consecutive duplicates of list elements into sublists. If a list contains repeated elements they should be placed in separate sublists. Example: * (pack '(a a a a b c c a a d e e e e)) ((A A A A) (B) (C C) (A A) (D) (E E E E))CL-USER> (defun pack (lst) (if (null lst) nil (let ((rl '()) (ra (list (car lst))) (first (car lst))) (loop for i in (cdr lst) do (if (equal first i) (setf ra (append ra (list i))) (progn (setf rl (append rl (list ra))) (setf ra (append '() (list i))) (setf first i )))) (setf rl (append rl (list ra))) rl))) STYLE-WARNING: redefining COMMON-LISP-USER::PACK in DEFUNPACKCL-USER> (pack lst) ((A A A A) (B) (C C) (A A) (D) (E E E E))CL-USER> 一个看起来更加lisp 的写法: (defun pack (l) (cond ((null l) nil)((atom l) (list l))((list l)(cond((eq (car l) (cadr l))(cons(append (list (car l)) (car (pack (cdr l)))) (cdr (pack (cdr l))) ))(t (cons (list (car l)) (pack (cdr l)))))) ))从效率上说,前面的循环比后面的递归写法,效率快10倍左右。 后面的递归不是尾递归实现。 P10 (*) Run-length encoding of a list. Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as lists (N E) where N is the number of duplicates of the element E. Example: * (encode '(a a a a b c c a a d e e e e)) ((4 A) (1 B) (2 C) (2 A) (1 D)(4 E))CL-USER> (defun count-element (lst) (if (null lst) nil (append (list (my-count (car lst))) (my-element (cdr lst)))))STYLE-WARNING: redefining COMMON-LISP-USER::COUNT-ELEMENT in DEFUNCOUNT-ELEMENTCL-USER> (defun my-count (lst) (cons (length lst) (car lst)))STYLE-WARNING: redefining COMMON-LISP-USER::MY-COUNT in DEFUNMY-COUNTCL-USER> (defun encode (lst) (count-element(pack lst))) STYLE-WARNING: redefining COMMON-LISP-USER::ENCODE in DEFUNENCODECL-USER> (encode lst) ((4 . A) (1 . B) (2 . C) (2 . A) (1 . D) (4 . E))CL-USER> (defun my-count(lst) (list (length lst) (car lst)))CL-USER> (encode lst) ((4 A) (1 B) (2 C) (2 A) (1 D) (4 E)) |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/133735/viewspace-750512/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/133735/viewspace-750512/