我正在尝试查找列表的模式
假设列表按升序排序
这是我的模式功能
(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
这是我的解决方案,它与奥斯卡尔的解决方案类似,但将最长/获胜结果的更新集中在一个地方:
(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))))))
我认为我的解决方案更短、更干净、重复性更小,但奥斯卡尔的解决方案的优点是更新变量的次数更少:他的解决方案只在运行结束时更新变量,而我的解决方法在当前长度比迄今为止看到的最长长度长时更新变量。
您的过程背后的逻辑是什么?您希望它如何通过从输入列表中删除元素来找到模式?你应该计算频率:
(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)))))))
它的工作原理是跟踪每个元素出现的次数,返回最频繁出现的元素——因为根据定义,模式是一组数据中最经常出现的值。我们利用了输入列表被排序的事实,因为我们知道,当当前元素与我们遇到的前一个元素不同时,一个新的重复元素序列就会开始。