코드는 적절한 형식 지정 없이는 읽기가 어렵습니다. if로 읽는 것이 더 쉬운 두 개의 분기 cond에 주목합니다.
set2bags의 else 절에서 (randlist 정렬)을 호출하지만 그대로 두십시오. 당신은 실제로 다음 s-expression (makepairs (sort randlist))에서 이것을 사용하고 싶습니다.
지금까지는 꽤 좋은 생각이었습니다.
이제 메이크 페어에서는 더 나은 추상화가 있어야합니다. 예를 들어, 변수를 첫 번째와 다른 것으로 먼저 말하십시오. inlist가 null 인 경우 함수는 null 목록이어야합니다. 그렇지 않으면 car가 like-first의 자동차 목록이고 like-first의 길이 인 cdr과 cdr이 makepairs를 호출 한 결과 인 쌍입니다. 달리 - 첫 번째 목록
(define (makepairs inlist)
(let ((like-first (filter (lambda (x) (equal? x (car inlist)) inlist))
(unlike-first (filter (lambda (x) (not (equal? x (car inlist))) inlist)))
(if (null? inlist)
'()
(cons (list (car inlist) (length like-first)) (makepairs unlike-first)))))
더 일종의 자신의 구현이있는 경우 effecient 버전
(define (makepairs inlist)
(if (null? inlist)
'()
(let loop ((firsts (list (car inlist)))
(but-firsts (cdr inlist)))
(if (or (null? but-firsts)
(not (equal? (car firsts) (car but-firsts))))
(cons (list (car firsts) (length firsts))
(makepairs but-firsts))
(loop (cons (car but-firsts) firsts) (cdr but-firsts))))))
]=> (makepairs (list 1 1 1 2 4 5))
;Value 17: ((1 3) (2 1) (4 1) (5 1))
, 머지 소트는 당신이 최고의 effeciency의 병합 부분에이 권리를 쓸 수 있다고 말한다.
(define (set2bags lst)
(mergesort2bags lst <))
(define (mergesort2bags lst pred)
(let* ((halves (divide-evenly lst))
(first-half (car halves))
(other-half (cadr halves)))
(cond ((null? lst) '())
((null? (cdr lst)) (list (list (car lst) 1)))
(else
(merge-bags
(mergesort2bags first-half pred)
(mergesort2bags other-half pred)
pred)))))
(define (divide-evenly lst)
(let loop
((to-go lst)
(L1 '())
(l2 '()))
(if (null? to-go)
(list L1 L2)
(loop (cdr to-go) (cons (car to-go) L2) L1))))
(define (merge-bags L1 L2 pred)
(cond ((null? L1) L2)
((null? L2) L1)
((pred (caar L1) (caar L2))
(cons (car L1) (merge-bags (cdr L1) L2 pred)))
((equal? (caar L1) (caar L2))
(cons (list (caar L1) (+ (cadar L1) (cadar L2)))
(merge-bags (cdr L1) (cdr L2) pred)))
(else (cons (car L2) (merge-bags L1 (cdr L2) pred)))))
(mergesort2bags (list 1 2 1 1 4 5) <)
;Value 46: ((1 3) (2 1) (4 1) (5 1))
나는이 방법이 많은 반복을 통해 매우 큰 데이터 세트에 대해 생각하고 있습니다.
yea. :/나는 카디널리티를 계산하는 방법을 몰랐다. 큰 도움. 감사. –
(구성표가 새로 생겼습니다.) 단지 재귀를 통해 수행 할 수 있는지 알고 싶습니까? –
@ user2662909 this _is_ recursion 사용. 나는 "반복"을 위해 "let"이라는 이름을 만들었는데, 나는 이것을 loop라는 이름으로 바꾼다. (원하는 이름으로 이름을 바꿀 수있다.) 그러나 실제로는 루프가 아니다 - 함수의 이름 일 뿐이다. '(loop ...) '라고 부르면 되풀이 함수 호출입니다. –