2016-10-17 2 views
1

저는 교육적인 이유로 라켓으로 코딩하고 있습니다.이 경우 누적 변수를 라켓에 주문하는 방법은 무엇입니까?

필자는 필터를 사용하지 않고 입력으로 목록을 받고 첫 번째 목록의 짝수에만 다른 목록을 반환하는 작업을해야한다는 과제를 받았습니다.

나는 반복적 인 과정이 재귀 적 정의를 내놓았다 :

(define (add-even lista) 
    (define (iter lista accu) 
    (cond ((null? lista) accu) 
      ((even? (car lista)) (iter (cdr lista) 
            (cons (car lista) accu))) 
      (else (iter (cdr lista) accu)))) 
    (iter lista empty)) 

그것은 잘 작동합니다. 그러나, 나는이 역순으로, 예컨대 :에 결과를 얻을

(add-even '(1 2 3 4 5 6 7)) 
>> '(6 4 2) 

I 입력에 모양의 동일한 순서로 출력을 가지고 어떻게해야합니까?

나는 역순으로 어떻게하는지 알고있다. 그러나 당신이 iter 절차없이 그것을 할 수 물론

답변

3

...

(define (add-even lista) 
    (cond ((null? lista) empty) 
     ((even? (car lista)) (cons (car lista) (add-even (cdr lista)))) 
     (else (add-even (cdr lista))))) 

(add-even '(1 2 3 4 5 6 7)) 
; => '(2 4 6) 

.. 매우 효율적인 방법이 아니다 그러나 나는 당신이 당신의 add-even 절차 꼬리 재귀를 유지하기 위해 그것을 사용하고 가정합니다. 그 다음의 경우 ... 만약 당신의 accu


cons 체인의 "구멍"채 웁니다 (대신 목록)을 절차이 될 수 있습니다. 계산이 끝날 때 accu을 반환하는 대신 마지막 값을 입력합니다.이 경우에는 empty이고 대신 identity으로 초기화됩니다.

나는 지금 당신이 꼬리 재귀를 얻을 당신이 앞으로 순서대로 목록을 작성 그래서

(define (add-even lista) 
    (define (iter lista accu) 
    (cond ((null? lista) (accu empty)) 
      ((even? (car lista)) (iter (cdr lista) 
            (λ (rest) (accu(cons (car lista) rest))))) 
      (else (iter (cdr lista) accu)))) 
    (iter lista identity)) 

(add-even '(1 2 3 4 5 6 7)) 
; => '(2 4 6)

변경 코드의 부분을 보여 굵은을 사용했다. 어떻게 작동하는지 보려면이 평가를 통해 단계별로 진행하는 것이 좋습니다. 이것은 continuation passing style입니다.


그리고 당신이 바르에게 조금

(define (add-even lista) 
    (define (iter lk) 
    (cond ((null? l) (k empty)) 
      ((even? (car l)) (iter (cdr l) 
           (λ (rest) (k (cons (car l) rest))))) 
      (else (iter (cdr l) k)))) 
    (iter lista identity)) 

(add-even '(1 2 3 4 5 6 7)) 
; => '(2 4 6)

이름을 변경 그리고 그것은 당신이 named-let

(define (add-even lista) 
    (let iter [(l lista)(k identity)] 
    (cond ((null? l) (k empty)) 
      ((even? (car l)) (iter (cdr l) 
           (λ (rest) (k (cons (car l) rest))))) 
      (else (iter (cdr l) k))))) 

(add-even '(1 2 3 4 5 6 7)) 
; => '(2 4 6)
를 사용한 경우에도 조금 더 정리하면 아마도 절차는 더 좋을 것이다

... 그리고 ANS까지 우리는 또한 짧은 함수를 작성하는 데 사용할 수있는 내장 for/list#:whencompose 및 라켓에

(define (add-even lista) 
    (let iter [(l lista) (k identity)] 
    (cond ((null? l) (k empty)) 
      ((even? (car l)) (iter (cdr l) (compose k (curry cons (car l))))) 
      (else (iter (cdr l) k))))) 

(add-even '(1 2 3 4 5 6 7)) 
; => '(2 4 6)
0

curry을 사용하는 경우도 더 :

(define (onlyeven lst) 
    (for/list ((i lst) #:when (even? i)) 
    i)) 

(onlyeven '(1 2 3 4 5 6 7)) 
; => '(2 4 6) 
+0

않을 것'필터 '여기가 좀 더 직접적 일까? – naomik

+0

OP는 특별히 필터가없는 함수를 생성하려고합니다 (질문의 두 번째 문장의 첫 번째 문장 참조). – rnso

관련 문제