2012-11-01 1 views
0

그래서 나는 lisp에서리스트를 평평하게하는 것을 보아왔다.lisp에서 평평하게 된리스트

그러나 내가 원하는 것은 레벨별로 목록을 평평하게하는 것입니다.

그래서 대신

(flatten '(a (b (d (g f))) e)) = (a b d g f e)

내가

(flatten '(a (b (d (g f))) e)) = (a b (d (g f)) e)

이 녀석을 수행하는 방법에 대한 어떤 생각을 할 필요?

많은 감사 =)

당신은 예를 들어 같은 것을, 할 수

답변

4

:

(defun fletten-level (tree) 
    (loop for e in tree 
     nconc 
     (if (consp e) 
      (copy-list e) 
      (list e)))) 

(fletten-level '(a (b (d (g f))) e)) 
;; (A B (D (G F)) E) 

이 원래 나무 최상위 지점을 통해 루프 및 분기는을 인 경우 포함하는 새로운 목록을 만듭니다 잎, 그 잎, 그리고 가지에 다른 두 가지 가지가있는 경우에는 첫 번째 잎과 나머지 가지가 모두 있습니다.

편집 : 죄송합니다. 실제로 처음에는 좋지 않았습니다. 이제는 수정해야합니다.

EDIT2 : 나 혼란에 빠졌기 때문에. (cons (car e) (cdr e))는 기본적으로 단지 e을 말하는 것과 같기 때문에 약간 이상하게 보입니다. 그러나 nconc은 conses를 파괴적으로 수정할 것이므로 (즉, 이전 cons 셀을 연결하는 대신 새로운 cons 셀을 생성하여)이를 수행해야합니다.

EDIT3 : 와우 ​​... 실제로는 원래 목록을 이렇게 수정합니다. copy-list이어야합니다.

3

Heres는 비파괴 버전에 내 신속하고 더러운 걸릴 :이 그것에 그것을 연결합니다 cons'ed 요소 인 경우, 트리를 산책하고 각 요소에 대해 재귀 함수가

(defun flatten-level (tree) 
    (cond ((null tree)()) 
     ((consp (car tree)) (concatenate 'list (car tree) 
             (flatten-level (cdr tree)))) 
     (t (cons (car tree) (flatten-level (cdr tree)))))) 

나무의 나머지는 납작하게되었다.

+1

다른 답변의 버전도 비파괴 적입니다. 그것은'nconc'를 구현 도구로 사용하지만'list' 또는'copy-list'로 새로 할당 된 구조체 만 변경합니다. 따라서, 추가 "consing"또는 재귀없이 하향식 방식으로 결과를 생성하므로 효율적입니다. 그것이 TRMC를 구현하는 시스템에 의해 ("꼬리 재귀 적 모듈러 cons") (http://en.wikipedia.org/wiki/Tail_call#Tail_recursion_modulo_cons)되는 코드가 plausibly * 컴파일 * 될 수 있습니다 (또는 자동으로 재 작성) 최적화. –

+0

아, 맞아. 설명해 주셔서 감사합니다! – user1582220

관련 문제