Scheme mode function

狂风中的少年 提交于 2020-01-06 13:10:50

问题


I am trying to find the mode of a list

Assuming the list is sorted ascending order

Here is my mode function

 (define freq
   (lambda (l)
     (cond ((null? l)l)
           ((null? (cdr l))l)
           ((not(equal? (car l) (car(cdr l))))(freq(cdr(delete l (car l)))))
           (else (freq (cdr l)))
 )))

   (freq '(4 4 4 4 5 7 9 9 9)) => should returns 4 but its returning 9 instead

回答1:


Here's my solution, which is similar to Óscar's solution but centralises the update of the longest/winning result in one place:

(define (longest-run lst)
  (let loop ((result #f)
             (cur #f)
             (count 0)
             (longest 0)
             (lst lst))
    (cond ((> count longest)
           (loop cur cur count count lst))
          ((null? lst) result)
          ((eqv? (car lst) cur)
           (loop result cur (+ count 1) longest (cdr lst)))
          (else
           (loop result (car lst) 1 longest (cdr lst))))))

I think my solution is shorter, cleaner, and less repetitive, but Óscar's solution has the advantage of updating the variables fewer times: his solution only updates the variables at the end of a run, whereas mine updates the variables whenever the current length is longer than the longest length seen so far.




回答2:


What's the logic behind your procedure? how do you expect it to find the mode by removing elements from the input list? you should be counting frequencies instead:

(define (mode lst)
  (if (null? lst)
      #f ; edge case: an empty list doesn't have a mode
      (let loop ((lst lst) ; list to traverse
                 (current (car lst)) ; current element in sequence
                 (counter 0) ; number of times current element appears
                 (max-current (car lst)) ; the mode
                 (max-counter 0)) ; number of times the mode appears
        (cond ((null? lst) ; the list is finished
               (if (> counter max-counter) current max-current))
              ((= (car lst) current) ; current element equal to previous
               (loop (cdr lst) ; add 1 to counter and keep iterating
                     current
                     (add1 counter)
                     max-current
                     max-counter))
              (else ; found a different element, a new sequence starts
               (loop (cdr lst)
                     (car lst) ; update current element
                     1
                     (if (> counter max-counter) current max-current)
                     (max counter max-counter)))))))

It works by keeping track of how many times each element appears, returning the element that appears most frequently - because by definition the mode is the value that appears most often in a set of data. We take advantage of the fact that the input list is sorted, because we know that a new sequence of repeated elements starts when the current element is different from the previous one we encountered.



来源:https://stackoverflow.com/questions/23208889/scheme-mode-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!