我正在尝试找到列表的模式
假设列表按升序排序
这是我的模式功能
(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
答案 0 :(得分:2)
您的程序背后的逻辑是什么?您如何通过从输入列表中删除元素来期望它找到mode?你应该计算频率:
(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)))))))
它的工作原理是跟踪每个元素出现的次数,返回最常出现的元素 - 因为根据定义,模式是在一组数据中最常出现的值。我们利用输入列表被排序的事实,因为我们知道当前元素与我们遇到的前一个元素不同时,重复元素的新序列开始。
答案 1 :(得分:2)
这是我的解决方案,类似于Óscar的解决方案,但将最长/获胜结果的更新集中在一个地方:
(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))))))
我认为我的解决方案更短,更干净,重复性更低,但Óscar的解决方案具有更新变量次数更少的优势:他的解决方案仅在运行结束时更新变量,而我的解决方案在当前更新变量长度比目前看到的最长长度长。