2013-09-07 8 views
2

는 다음과 같은 기록의 더 나은 ⁄ 짧은 방법이 있나요? 아마도 변환을 수행하는 라이브러리가 있지만 어떤 종류의 지도 또는 접미어이 작동하는지 궁금합니다. 라켓에지도 또는 접기를 사용하여 가중치를 범위로 변환하는 더 나은 방법은 무엇입니까?

(define (weights-to-range lw) 
    ; '(1 4 6 6 6 6 6) -> (1 5 11 17 23 29 35) 
    (define (f x lw acc) 
    (if (null? lw) 
     acc 
     (let ([y (+ x (car lw))]) 
      (f y (cdr lw) (append acc (list y)))))) 
    (f (car lw) (cdr lw) (list (car lw)))) 
+0

출력의 초기 0이 암시한다고 생각하십니까? –

답변

3

나는 아마이 for/fold 지능형리스트를 사용하여 작성합니다

(define (weights-to-range weights) 
    (define-values (xs _) 
    (for/fold ([xs '()] [prev 0]) 
       ([weight (in-list weights)]) 
     (define this (+ prev weight)) 
     (values (cons this xs) this))) 
    (reverse xs)) 

(require rackunit) 
(check-equal? (weights-to-range '(1 4 6 6 6 6 6)) 
       '(1 5 11 17 23 29 35)) 

이이 fold/fold에 두 개의 누적 값을 제공하기 때문에 그것은, 것을 제외하고도 간단한 것 - xsprev - - for/fold 양식은 두 개의 값을 반환합니다. xs에서 - - reverse에 그래서 우리는 모두 우리가 관심을 전달하기 전에, define-values를 사용하여 일시적으로 바르에 정력해야합니다. (prev에 대한 VAR는 _ 지정됩니다. 우리가 그것을 필요로하지 않기 때문에 즉, "무시"를 의미 단지 컨벤션입니다.) 물론


, 여기에 일반적인 생각은을 사용하여 목록을 "배"하는 것입니다 쌍의 "슬라이딩 윈도우 (sliding window)"로 각 단계마다 누적 결과를 이용할 수 있습니다. 귀하의 경우, 함수는 +이지만 일반화 될 수있다 :

(define (fold-slide f vs) 
    (define-values (xs _) 
    (for/fold ([xs '()] [prev 0]) 
       ([v (in-list vs)]) 
     (define this (f prev v)) 
     (values (cons this xs) this))) 
    (reverse xs)) 

을 같은 fold-slide 기능 (더 나은 이름의 부족), 당신은 단순히 작성한 수와 함께 :

(fold-slide + '(1 4 6 6 6 6 6) 

이러한 그것은 단지 2

PS, 어떤 크기의 "창"을 처리 할 수있는 경우 fold-slide 더욱 유용 할 수 있습니다 SRFI에서 이와 같은 작업을 수행 할 수있는 가능성이 있습니다. 아니면 내가 모르는 Racket에서보다 우아한 방법을 사용할 수도 있습니다.

+0

나는 그것을 시도해 보았고 나는이 정확한 해결책을 생각해 내었다. – stchang

2

아직 (마지막에 반전 후 즉, 대신 반전 대답을 축적하고) 직접 답을 구축하면서 축적을 완벽하게 괜찮아요.

;; weights-to-range : (listof number) -> (listof number) 
;; Returns list of partial sums of input list. 
(define (weights-to-range lw0) 

    ;; helper : (listof number) number -> (listof number) 
    ;; acc is the sum of elements seen so far 
    (define (helper lw acc) 
    (cond [(null? lw) 
      null] 
      [else 
      (let ([new-acc (+ acc (car lw))]) 
      (cons new-acc (helper (cdr lw) new-acc)))])) 

    (helper lw0 0))