2009-07-17 5 views
4

비슷한 상품의 평균 가격을 기준으로 새 상품의 가격을 찾고 싶습니다. get-k-similar 함수는 k-Nearest Neighbors를 사용하지만이 출력은 ((list rating age price) proximity)입니다.Scheme/Lisp에서이 데이터 구조에 대한 평균 함수를 작성하는 방법은 무엇입니까?

For example, 2-similar would be: 
(((5.557799748150248 3 117.94262493533647) . 3.6956648993026904) 
((3.0921378389849963 7 75.61492560596851) . 5.117886776721699)) 

비슷한 항목의 평균 가격을 찾아야합니다. 즉 평균 117 및 75입니다. 반복 할 수있는 더 좋은 방법이 있습니까? 내 기능이 너무 추해 보입니다.

(define (get-prices new-item) 

    (define (average-prices a-list) 
    (/ (cdr 
     (foldl (λ(x y) (cons (list 0 0 0) 
          (+ (third (car x)) (third (car y))))) 
       (cons (list 0 0 0) 0) 
       a-list)) 
     (length a-list))) 

    (let ((similar-items (get-k-similar new-item))) 
     (average-prices similar-items))) 
+0

자유롭게 코드를 들여 쓰기 위해 자유롭게했습니다. 나는 이것이 의미있는 것을 출력한다고 상상할 수 없다. – Svante

답변

3

당신은 간단한 일을 그냥 세 번째마다 값 당겨 수 있습니다

(define (average-prices a-list) 
    (/ (apply + (map fourth a-list)) (length a-list))) 

이 조금 비효율적이다 중간체를 만들기 때문에 목록, 그리고 내 추측은 이것이 당신이 시도한 이유입니다 foldl. 여기에 그렇게 할 수있는 권리 방법 : - length 두 번째 검사를하고있다 -

가 작은 비 효율성은 여전히있다
(define (average-prices a-list) 
    (/ (foldl (lambda (x acc) (+ (third x) acc)) 0 l) 
    (length a-list))) 

하지만 그건 당신이 당신이 어떤 정말 필요 했어 이후에 대해 신경 안 뭔가 긴 목록은 눈에 띄는 둔화를 일으 킵니다.

+0

당신은 흥미로운 점을 제기했습니다. 항목을 추가 할 때 목록의 길이를 누적 할 수 있습니까? – unj2

+0

물론, 여러 가지면에서 명령적이고 기능적입니다. 하지만이 단계에서 나는 너라면 나에 대해 걱정하지 않을 것이다. –

5

커먼 리스프

(/ (reduce '+ a-list :key 'caddar) (length a-list)) 

또는

(loop for ((nil nil e) . nil) in a-list 
     count e into length 
     sum e into sum 
     finally (return (/ sum length)))