2010-05-14 3 views
0

내가 가진이진 트리

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d))) 

(defun drumuri (l3) 
    (cond ((atom l3) (cons l3 nil)) 
    (t (append 
      (cons (car l3) nil) 
      (drumuri (cadr l3)) 
      (cons (car l3) nil) 
      (drumuri (caddr l3)))))) 

(drumuri l2) 

에 대한 리스프 코드와 관련된 도움 그리고 그것은 나를 제공 : 내가 필요

Break 2 
[4]>  DRUMURI 
Break 2 
[4]>  (1 2 B 2 C 1 C B 1 A 1 2 1 NIL A D) 

있지만에게 : 내가 몇 가지를 발견

((1 2 B)(1 2 C 1)(1 2 C B)(1 A 1 2)(1 A D)) 

좋아 좋은 소식을 답변 :

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d))) 
(defun drumuri (l3) 
(cond ((atom l3) (cons l3 nil)) 
     (t (append (cons (car l3) nil) 
      (drumuri (cadr l3)))))) 
      (drumuri l2) 
,

그에 대한 대답은 다음과 같습니다

(defun drumuri (l4) 
    (cond ((atom l4)(cons l4 nil)) 
    (t (append (cons (car l4)nil) 
     (drumuri (caddr l4)))))) 
      (drumuri l2) 

그에 대한 대답입니다 : : 그래서 모든 남아있는 그이다

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D)) 
[2]> 
DRUMURI 
[3]> 
(1 A D) 

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D)) 
[2]> 
DRUMURI 
[3]> 
(1 2 B) 

다음 두 번째 답변입니다 발견 :

(1 2 1) (1 2 1)

+0

코드를 포맷하고 탭을 공백으로 대체하십시오 - 텍스트를 선택하고 편집기에서 "101010"버튼을 누르십시오. –

+0

들여 쓰기는 Lisp을 프로그래밍 할 때 명확성을 위해 매우 중요합니다. 이 문제를 해결했지만 미래를 염두에 두십시오. –

+0

덕분에 하지만 – iulia

답변

1

까다로운 문제입니다. 특히 복잡하지는 않지만 까다로운 가장자리가 있습니다. 이것은 분명히 숙제이기 때문에, 나는 당신을 도우려고 노력할 것입니다. 그러나 동시에 당신에게 숟가락 먹이는 것만 피하십시오 (그리고 아마도이 목표들 중 하나 또는 둘 모두에서 실패 할 것입니다). 그래서 파이썬으로 작성했습니다. Lisp에서 충분히 멀리 떨어져 있기 때문에 여전히 좋은 생각을 할 수 있기를 바랍니다.

>>> import operator 
>>> def drumuri(a): 
...  if isinstance(a, list): 
...   return reduce(operator.add, 
...      [[a[:1] + d for d in drumuri(x)] for x in a[1:]]) 
...  else: 
...   return [[a]] 
... 
>>> drumuri([1, [2, 'b', ['c', 1, 'b']], ['a', [1, 2], 'd']]) 
[[1, 2, 'b'], [1, 2, 'c', 1], [1, 2, 'c', 'b'], [1, 'a', 1, 2], [1, 'a', 'd']] 
>>> 

다음은 Lisp 버전에서 부족한 핵심 통찰력입니다. 드럼 루리는 반복적이기 때문에 모든 레벨은 호출자에게 동일한 종류의 구조, 즉 각 경로가 목록 인 경로 목록을 반환해야합니다. 요컨대, 드럼 루리는 항상리스트의 목록을 반환해야합니다. 리프 케이스는 단일 원자를 포함하는 목록을 반환합니다.

또한 append을 사용하여 실수를 저지르고 있지만 리프 문제로 인해 모양이 엉망입니다.

편집 : 직접 솔루션을 찾을 수 있는지 알아 봅시다. 다음 단계에 따라

  1. 은 하나의 머리와 경로 목록을 받아, 머리가 각각의 원래 경로의 앞에 추가 된 경로 목록을 반환 prepend-to-paths라는 함수를 작성합니다. 다음과 같이 작동합니다 :

    > (prepend-to-paths 1 '((2 B) (2 C 1) (2 C B) (A 1 2) (A D))) ;' 
    ((1 2 B) (1 2 C 1) (1 2 C B) (1 A 1 2) (1 A D)) 
    
  2. 는 처리되지 않은 꼬리 요소의 목록을 소요하고이 경로로 변환 convert-to-paths라는 함수를 작성합니다. 그러나 모든 작업 자체를 수행하는 대신 입력을 경로 목록에 매핑하는 방법 (각 요소를 매핑하기 위해 아직 작성되지 않은 drumuri에 의존)에 대해 염려해야하며 반환 된 경로 목록을 연결하여 단일 목록으로 경로. 출력은 (일단 drumuri 존재)과 같이 같아야

    > (convert-to-paths '((2 b (c 1 b)) (a (1 2) d))) ;' 
    ((2 B) (2 C 1) (2 C B) (A 1 2) (A D)) 
    
  3. drumuri 함수를 작성한다.그런 다음 이전 단계에서 당신이 쓴 기능을 사용하는 코드로 (append ...) 교체

    > (drumuri 'b) ;' 
    ((b)) 
    

    : 그것은 당신의 원본에 따라 cond 사용하지만, 경로의 목록으로 원자를 반환하는 식으로 잎 케이스를 교체해야합니다 입력리스트의 선두와 말미를 변환 해 패스의리스트를 입력합니다.

  4. 일단 세 기능이 잘 작동하면 drumuri의 본문에 처음 두 개를 접는 방법을 알아낼 수 있습니다. 이 결과는 필자가 제공 한 Python 솔루션과 구조적으로 다를 수 있습니다.

막혔을 때 진행 한 모든 진행 상황과 함께 관리 할 수있는 코드로 질문을 업데이트하십시오.

+0

marcelo 덕분에 많은 도움을받을 수 있습니다. 차, cddr 또는 다른 것들을 배치하는 것이 도움이 될 수만 있다면 도움이 될 것입니다. ..이 프로그램으로 내 한계에있다 : ( – iulia

+0

2 단계지도 작업을 사용하는 경우 caddr, 자동차 및 cdr이 필요하지 않습니다. 오늘 내가 나중에 좀 더 도움을 줄 수 있는지 알 수 있습니다. 지금 작업에 늦었습니다. 죄송합니다.) –

+0

몇 가지 해답을 제시했으나 해결책이 없습니다. hellpppp :(Marcelo – iulia