2017-05-08 12 views
1

DrRacket 사용자입니다.While 루프가 프로그램에서 Scheme의 프로그램 작동 메커니즘

나는이 프로그램이 어떻게 작동 하는지를 이해하기 위해 고심하고있다. 나는 그것을 직접 썼다. 그것이해야 할 일을하지만 나는 어떻게 이해할 수 없다.

(define (while test body) 
    (if (test) 
     (begin 
     (body) 
     (while test body)) 
     (void))) 

가 지금은 변경 가능한 목록의 각 요소에 주어진 절차를 적용하는 프로그램을 작성해야합니다으로

나는 동안 루프를 정의합니다.

list1 (mlist 1 2 3) 

을 정의하고 우리가 '(2 3 4)를 얻을

(mlist-map-while (lambda (x) (+ x 1)) list1) 

을 적용 그래서

(define (mlist-map-while f x) 
    (while (lambda() (not (null? x))) 
    (lambda() 
     (set-mcar! x (f (mcar x))) 
     (set! x (mcdr x)))) 
    (void)) 

: 내가 쓴 다음

.

내가 이해하지 못하는 것은 내가 여기

(set! x (mcdr x)) 

-mcar! 쓸모하고 있어야합니다 설정하는 첫 번째 절차 쓴 어떻게 끝낼 경우 때문에리스트의 첫 번째 요소는, 그 안에 유지하는 방법이다 두 번째와 겹쳐졌다. 이 예와 같이 :

(define list1 (mlist 1 2 3)) 
(set-mcar! list1 9) 
(set-mcdr! list1 (mcdr list!)) 

첫 번째 요소는 부족하지만이 프로그램은 아무 것도 남기지 않고 원하는 출력을 제공합니다. 나는 그것이 어떻게 작동하는지 그리고 주어진리스트를 횡단하는 다른 방법이 있는지 알고 싶다.

답변

0

set-cdr! abd set! 사이에 큰 차이가 있습니다. 첫 번째는 쌍의 cdr 포인터를 변경하고 후자는 바인딩을 변경하므로 이름이 가리켜 야하는 포인터가 변경됩니다. 당신의 mlist-map-while 변수 x에서

다음 cdrx의를로, x 무엇을 나타내는 변화는 car 변경합니다.

(define list1 (mlist 1 2 3)) 
(define list1-ref list1)  ; variable pointing to the same value as list1 
(set-mcar! list1-ref 9)  ; set-car! changes the pair 
(set! list1-ref (mcdr list)) ; set! updates what list1-ref points to 
list1 ; ==> (9 2 3) 
list-ref ; ==> (2 3) 

당신은 할 수 있습니다 : 그것은은 더이처럼 따라서 ... cdr 그렇게 list1 바인딩 항상 x 점 동안 먼저 다음 두 번째, 등등에 첫 번째 쌍를 가리키는

을 변경하지 재귀와 함께, set!를 사용하지 않고 같은 방식으로 목록을 반복 : 우리는 재귀 여기

(define (fold function init lst) 
    (if (null? lst) 
     init 
     (fold function 
      (function (car lst) init) 
      (cdr lst)))) 

(fold + 0 '(1 2 3) 
; ==> 6 

(fold cons '() '(1 2 3)) 
; ==> (3 2 1) 

사항을 변경 무엇 012,305,은 cdr이됩니다. 모든 재귀에는 고유 한 lst이 있으며 발신자 자신과 혼동하지 마십시오. 귀하의 예에서는 돌연변이없이 set!과 동일하게 처리됩니다.

+0

그렇다면 list1-ref를 예제에서와 같이 정의하면 (set!list1-ref (mcdr list))) 값 2와 3은 여전히 ​​list1의 두 번째와 세 번째 값을 가리 킵니까? 그리고 그것들을 변경하면 list1의 값이 각각 변경됩니다. – Dmitrii

+0

예. 목록을 모델링하는 방법 때문에 각 요소 쌍에는 하나의 요소와 나머지 목록에 대한 링크가 있습니다. '(mlist 1 2 3)'은'(mcons 1 (mcons 2 (mcons 3 '()))))와 같다. – Sylwester

+0

제도는 TCO 보증을하고있다. –