Counting unique elements in Scheme

2019-05-28 19:59发布

问题:

Write a recursive Scheme procedure count-dist elements that takes a list with duplicate elements and returns the number of distinct elements in the list.

This is my code, but it is not working correctly. Please help! Thanks!!

(define (count-dist-elements lis)   
  (cond
    ((null? lis) 0)
    ((null? (cdr lis))0)
    ((member (car lis)(cdr lis)))
     (else(+ 1(count-dist-elements (cdr lis))))))

p/s: let it be (count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9))

回答1:

It looks like you're getting pretty close.

  • What happens when you pass your function a list with one element? What should your function return in this case?
  • What about a two-element list with the same element (eg. (5 5))? Does your function return a sensible value?


回答2:

First: Why are you returning zero in the (null? (cdr lis)) case?

Second: What do you think your code returns in the case where the first element also occurs later in the list? Are you sure?



回答3:

 (define (count-dist-elements lst dist-elems count)
   (cond ((null? lst) count)
         ((member (car lst) dist-elems)
          (count-dist-elements (cdr lst) dist-elems count))
         (else
          (count-dist-elements (cdr lst)
                               (cons (car lst) dist-elems)
                               (+ 1 count)))))

(count-dist-elements '(a b b c) '() 0) ==> 3

(count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9) '() 0) ==> 9

Or, if you want it recursive and not iterative (and, it has to use a function call like the one shown),

(define (count-dist-elements lst . dist-elems)
  (let ((dist-elems (if (null? dist-elems) '() (car dist-elems))))
    (cond ((null? lst) 0)
          ((member (car lst) dist-elems)
           (count-dist-elements (cdr lst) dist-elems))
          (else
           (+ 1 (count-dist-elements (cdr lst) (cons (car lst) dist-elems)))))))

Gives the same results.

(count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9)) ==> 9