들여 쓰기를 수정, 코드는 머리 감시 트릭을 사용
(define (children? node)
(define list '(1))
된다. 좋은 잘...). 그러나 그 목적이 외과 적으로 변경 될 예정이므로, 데이터는 인용되지 않고 새로 작성되어야합니다.
(define list (list 1))
무엇을 기다려야합니까? 두 list
? 이것은 Common Lisp이 아닙니다. 그렇습니까? Scheme은 Lisp-1이 아니라 Lisp-2입니다. 함수와 값의 이름은 같은 네임 스페이스에 있습니다. 그래서; 하지마. 연속
(define lst (list 1))
(map (lambda (x)
(cond
((equal? (car x) node)
(if (equal? list '(1))
(set-car! list x)
(append! list x)))))
두 조건은 단지 and
이지만, 더 중요한 것은, 머리 감시 트릭은 (cdr lst)
으로 진정한 결과를 반환 할 수 있습니다 의미, 그래서 머리의 내용을 변경할 필요가 없습니다. 그런 다음 코드가 단순화됩니다. 첫 번째 위치에서 헤드 센티널을 사용하는 것이 목적입니다.
대체 절이 없습니다. 일반적으로 눈살을 찌푸 리지 만, 여기에서는 부작용에 대한지도를 작성합니다. 따라서 이이 아니라면 map
의 결과를 사용하면됩니다. 쉽게하지만 단지 항상이
(map (lambda (x)
(if (equal? (car x) node)
(append! lst x) ; append two lists together... (see below)
#f))
data)
data
처럼, 습관과 좋은 스타일의 문제로 대체 절을 처리하는 것입니다? 그게 뭐야? 다른 형식 매개 변수로 children?
을 추가해야합니다.
(if (equal? lst '(1))
equal?
? 왜? 우리가 그것을 변경했을 여부를 확인하기 위해서는 충분한 단지
(if (null (cdr lst))
이상 행동 원칙이다 ...
#f
(cdr lst))) ; cdr carries the true payload
(그러니까 기본적으로,
(define (children? node data)
(let ((res (filter (lambda (x) (equal? (car x) node))
data)))
(if (not (null? res))
res
#f)))
). 좋은. 그렇지? 글쎄요, 다음 작업에 따라 달라집니다. 그것은
(define (append! lst . lsts)
(if (not (null? lsts))
(if (null? (cdr lst))
(begin
(set-cdr! lst (car lsts))
(apply append! (car lsts) (cdr lsts)))
이 목록을 추가, 그래서 (append! (list 1) (list 2))
는 (list 1 2)
및 (append! (list 1) (list 2 3))
(list 1 2 3)
같은 같은 결과를 반환합니다. 목록 끝에 (2
과 같은) 항목을 추가하려면 먼저 다른 목록에 넣어야했습니다. 따라서 추가되는 항목이 자체 목록 인 경우 '(2 3)
과 같이 '(1 (2 3))
을 다시 가져오고 싶습니다. 그리고 그것을 위해, 항목은 추가되기 전에 목록에 동봉되어야합니다. 그래서 당신의 기능을 수정해야합니다.
(apply append! (cdr lst) lsts))))
그리고 여기 당신의 마지막 셀, 다시 다시 각 항목에 대한 추가되고를 찾기 위해 (성장) 결과 목록을 검색합니다. 마지막 셀 포인터를 직접 유지하고 직접 사용하여이를 해결할 수 있습니다. 그 "포인터"는 무엇입니까? 그것은 lst
입니다.이 때마다 cdr
은 append!
입니다. 그래서 직접 (set-cdr! lst (list item))
을 할 수 있습니다. 물론 lst
변수를 사용할 수는 없습니다 (왜?).
귀하의 들여 쓰기 모든 잘못, 당신은 필요하지 않은 파괴적인 목록 수정을 사용하지 말아야하고,'data'이 실제로 어떻게 생겼는지의 예를 제공해야한다. 즉, 아마'list' 나'cons'를 사용해야하는 곳에서'append'를 사용하고있을 것입니다. –