2014-04-30 8 views

답변

2

일반적인 기술은 처리하려는 요소의 목록을 먼저 작성하는 것입니다. 이미이 목록이 있습니다. 그런 다음 하나 이상의 변환을 입력 목록에 적용하려고합니다. 이 경우 변환 할 필요가 없습니다. 그런 다음 특정 조건을 만족하는 요소 만 가져 오도록 목록을 필터링합니다. 마지막으로 필터링 된 목록의 요소를 결합하는 연산을 적용합니다. 우리는 이미 우리의 입력 목록을 가지고 있기 때문에

처리 목록이 일반적인 방법은 이제

enumerate -> transform (map) -> filter -> accumulate 

SICP에 설명되어

,이 경우, 우리는하지 필요 열거 에을하거나 아무것도지도 나는 이전에 언급했다.

(define (filter predicate sequence) (cond 
    ((null? sequence) '()) 
    (else (cond 
    ((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence)))) 
    (else (filter predicate (cdr sequence))))))) 



(define (accumulate op initial sequence) (cond 
        ((null? sequence) initial) 
        (else (op (car sequence) (accumulate op initial (cdr sequence)))))) 


(define (sum-list list) (accumulate + 0 (filter (lambda(x) (cond ((> x 10) #t) (else #f)))list))) 


(sum-list (list 1 2 3 45 12)) 
;Output: 57 

predicate은 true 또는 false로 평가되는 조건이다.

2

: BTW

(define suma 
    (lambda() 
    (apply + (filter (lambda (e) (> e 10)) lista_de_elemente)))) 

, suma는 인수로 목록이 있어야합니다

(define suma 
    (lambda(lst) 
    (apply + (filter (lambda (e) (> e 10)) lst)))) 

(suma lista_de_elemente) 
1

보다 큰 숫자를 필터링하여 목록을 반환하는 기능을 추가하기 10. 그 값을 그대로 apply으로 전달합니다. 오히려 필터를 통합하는 스마를 정의하는 것이 아니라, 일반화 된 suma을 유지하려면 당신이 대신 합하는 스마를 정의하고 필터링 할 수 있습니다

(define suma 
    (lambda() 
     (apply + (get-greater-than-ten lista_de_elemente)))) 
1

:

(define (get-greater-than-ten lst) 

    (define (helper in out) 
    (if (null? in) 
     out 
     (if (> (car in) 10) 
     (helper (cdr in) (append out (list (car in)))) 
     (helper (cdr in) out))) 

    (helper lst `())) 

이 좋아 사용 당신은 매개 변수로 통과 목록 :

(define elems (list 2 4 1 12 32 3 34 12)) 

(define (suma lst) 
    (apply + lst)) 

(suma (filter (lambda (x) (> x 10)) elems)) 

는 이제 일반화 된 sum있어, 당신은 원래 목록 그쪽 부분 만 그것을 통과 너는 합계하려고한다.

4

나는 당신이 좀 그래서 당신이 할 수있는 filter-sum 등을 만든 일반화 할 수 있습니다 상상 : 여기

#!r7rs        ; #!r6rs for r6rs 
(import (scheme)      ; replace scheme with rnrs for r6rs 
     (only (srfi :1) filter fold)) ; remove filter for r6rs 

;; I renamed you list 
(define *lista-de-elemente* '(2 4 8 10 12 14 16)) 

(define (suma) 
    (define (>10? x) 
    (> x 10)) 

    (filter-sum >10? *lista-de-elemente*)) 

(suma) ; ==> 42 

filter-sum의 몇 가지 가능한 버전입니다. 우리는 똑바로 앞으로 재귀 방법이 있습니다

(define (filter-sum predicate lst) 
    (cond ((null? lst) 0) 
     ((not (predicate (car lst))) (filter-sum predicate (cdr lst))) 
     (else (+ (car lst) (filter-sum predicate (cdr lst)))))) 

을하지만 주문 또는 숫자가 중요하지 않기 때문에 매우 좋지 않다. 꼬리 재귀와

(define (filter-sum predicate lst) 
    (let loop ((lst lst)(acc 0)) 
    (if (null? lst) 
     acc 
     (loop (cdr lst) 
       (if (predicate (car lst)) 
        (+ acc (car lst)) 
        acc))))) 

지금과 같은 루프를하고 축적은 배로 변환 할 수 있습니다 : 우리는 대신에 겨드랑이 절차의 명명 된 let 여기, 어큐뮬레이터와 재귀이 꼬리를 할 수 있습니다. 추가하거나하지 말아야 경우 대부분의 코드

(define (filter-sum predicate lst) 
    (fold (lambda (x acc) 
      (if (predicate x) 
       (+ acc x) 
       acc)) 
     0 
     lst)) 

현재 상황 : 당신은 SRFI-1 list library에 접어 찾을 수 있습니다. 겹의 모든 요소를 ​​추가 할 수 있도록 filter하면 필터링 할 수 있습니다 :

(define (filter-sum predicate lst) 
    (fold + 0 (filter predicate lst))) 

filter는 SRFI-1 목록 라이브러리도있다. 이제 10보다 큰 수의 목록이 짧다는 것을 안다면 ... foldapply으로 완전히 바꿀 수 있으며 그 수가 조금 더 빨라질 수도 있지만 목록 길이에 제한이 있습니다. (많은 스킴 시스템은 제한된 크기의 스택에서 인수를 푸시하는 반면 폴드는 한 번에 하나의 요소를 누적합니다.)