2009-09-14 4 views
2

어떻게 모든 하위 목록도 반전되도록 목록을 반대하는?LISP : 멀티 레벨 재귀 역 기능

(defun REV (L) 
    (cond 
    ((null L) nil) 
    ((listp L) 
    (append 
     (REV (cdr L)) 
     (list (car L)))) 
    (t 
    (append 
     (REV (cdr L)) 
     (list (car L)))))) 

답변

5

당신은 바른 길에 있지만, 마지막 두 가지 조건 중 하나가 무엇을해야하고되지 않는다는 표시를 제공해야합니다 같은 조치를 보유하고 있습니다. 사실, 두 번째 조건 인 listp 대/소문자는 목록이 아니므로 수정되지 않은 목록 대신 목록의 역순을 추가해야하기 때문에 올바르지 않습니다. 가능한 해결책은 : 당신이 볼 수 있듯이

(defun reverse (l) 
    (cond ((null? l) nil) 
     ((listp (car l)) (append (reverse (cdr l)) 
           (list (reverse (car l))))) 
     (t 
      (append (reverse (cdr l)) 
        (list (car l)))))) 

> (reverse '((1 2 3) (4 5 6))) 
((6 5 4) (3 2 1)) 

, 유일한 차이점은 첫 번째 요소가리스트 인 경우 테스트하고 있는지, 당신이 그것을 추가하기 전에 첫 번째 요소를 반대한다는 것이다.

+1

약간 짧은 : (내-역 (L)를 DEFUN(if (null l) nil (append (my-reverse (cdr l)) (my-reverse (car l)) (car l))))))))))))) – jlf

0

은 숙제 문제 :

당신이 정기적으로 역 코드를 작성하여 시작처럼 보이는 것 같은데 : 이것은 내가 지금까지있는 것입니다. 나는 당신에게 힌트를 줄 것이다 : 두 번째 조건 (listp L)이 옳지 않다 (항상 맞을 것이다). 다른 것이 목록인지 확인하려고합니다.

2

나는 이런 식으로 쓰는 것 :

(defun reverse-all (list) 
    (loop 
    with result = nil 
    for element in list 
    if (listp element) 
    do (push (reverse-all element) result) 
    else do (push element result) 
    finally (return result))) 
0

dmitry_vk의 대답은 더 lispish 방법으로 (아마 더 빨리 대부분의 lisps에서 앞의 예에서 추가 사용하는 것보다) :

(defun reverse-all (list) 
    (let ((result nil)) 
    (dolist (element list result) 
     (if (listp element) 
      (push (reverse-all element) result) 
      (push element result))))) 

을 심지어 :

(defun reverse-all (list) 
    (let ((result nil)) 
    (dolist (element list result) 
     (push 
     (if (listp element) (reverse-all element) element) 
      result))))