List 查找每个数字在列表中出现的次数
如果我们有一个列表List 查找每个数字在列表中出现的次数,list,functional-programming,scheme,histogram,frequency,List,Functional Programming,Scheme,Histogram,Frequency,如果我们有一个列表a包含(123444),那么我们如何才能得到一个新的列表B,其中包含((1.30)(2.20)(3.20)(4.30)),这样,u点后的数字是列表a中u点前的数字的百分比 例如1是列表A的30%,2是列表A的20%,等等 (1.30)是一对,它可以由(cons130)组成。我想你要做的是计算列表中每个元素的百分比。您使用了“unique”一词,但这有点令人困惑,因为您的列表没有唯一的元素。这是基于您的示例输入和输出,其中列表(1 2 1 3 4 4)由“30%的”组成 您可以将
a
包含(123444)
,那么我们如何才能得到一个新的列表B
,其中包含((1.30)(2.20)(3.20)(4.30))
,这样,u点后的数字是列表a
中u点前的数字的百分比
例如1
是列表A
的30%,2
是列表A
的20%,等等
(1.30)
是一对,它可以由(cons130)
组成。我想你要做的是计算列表中每个元素的百分比。您使用了“unique”一词,但这有点令人困惑,因为您的列表没有唯一的元素。这是基于您的示例输入和输出,其中列表(1 2 1 3 4 4)
由“30%的”组成
您可以将其大致分解为一个递归算法,由以下步骤组成:
cdr
中删除第一项的所有匹配项cons
创建一个(element.percentage)
对的列表过滤器:
> (filter (lambda (x) (eq? (car A) x)) A)
(1 1 1)
对于列表A,这将返回列表(1)
。然后,我们可以使用长度来获得它发生的次数:
> (length (filter (lambda (x) (eq? (car A) x)) A))
3
要计算百分比,请除以整个列表中的元素数,或(长度A)
,然后乘以100:
> (* 100 (/ (length (filter (lambda (x) (eq? (car A) x)) A)) (length A)))
30
使用元素(car A)
很容易cons
得到最终列表中的一对
要执行第二步,我们可以使用remove
,它是过滤器的逆函数:它将返回原始列表中不满足谓词函数的所有元素的列表:
> (remove (lambda (x) (eq? (car A) x)) A)
(2 2 3 3 4 4 4)
这是我们希望递归的列表。请注意,在每个步骤中,都需要原始列表(或原始列表的长度)和新列表。因此,您需要以某种方式使递归过程可以使用它,或者使用一个额外的参数,或者定义一个内部定义
我相信可能有更有效的方法,或者只是其他方法,但这是我在阅读问题时想到的解决方案。希望有帮助
(define (percentages all)
(let ((len (length all))) ; pre-calculate the length
;; this is an internal definition which is called at ***
(define (p rest)
(if (null? rest)
rest
;; equal-to is a list of all the elements equal to the first
;; ie something like (1 1 1)
(let ((equal-to (filter (lambda (x) (eq? (car rest) x))
rest))
;; not-equal-to is the rest of the list
;; ie something like (2 2 3 3 4 4 4)
(not-equal-to (remove (lambda (x) (eq? (car rest) x))
rest)))
(cons (cons (car rest) (* 100 (/ (length equal-to) len)))
;; recurse on the rest of the list
(p not-equal-to)))))
(p all))) ; ***
这个问题的表述非常接近于这个概念。在运行长度编码方面,您可以使用一种简单的策略:
排序李>
运行长度编码李>
缩放运行长度以获得百分比
您可以像这样实现运行长度编码:
(define (run-length-encode lst)
(define (rle val-lst cur-val cur-cnt acc)
(if (pair? val-lst)
(let ((new-val (car val-lst)))
(if (eq? new-val cur-val)
(rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
(rle (cdr val-lst) new-val 1 (cons (cons cur-val cur-cnt) acc))))
(cons (cons cur-val cur-cnt) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
缩放看起来像:
(define (scale-cdr count-list total-count)
(define (normalize pr)
(cons (car pr) (/ (* 100 (cdr pr)) total-count)))
(map normalize count-list))
现在我们需要一些东西来对列表进行排序。我将只使用racket中的排序
功能(根据需要进行调整)。计算列表中每个数字的百分比的函数是:
(define (elem-percent lst)
(scale-cdr (run-length-encode (sort lst <)) (length lst)))
我不明白你对代码应该做什么的说明。如何计算输出列表中的数字?你的函数似乎做了它们应该做的事情。我不确定我是否理解你,但任务的目的是获取列表A中所有唯一的数字,并且在列表中有频率。我可以写FUNCTION(成员x l),但我不知道如何在列表A中获得唯一的数字及其计数什么是(1.30)
?你是说(1.30)
?是的,这是一对,它可以由(cons130)
制成,然后不要把它写成(1.30)
,因为它显然是其他东西。也许,你是对的!“独一无二”这个词不太适合这个词。作为列表A中的唯一元素,我理解没有PED的元素。昨天,我知道我们可以使用函数删除重复。该函数接受list'(12343444)和output'(1234)。这使得这个问题有点容易,但我仍然不知道如何做。今天晚些时候我将阅读你的完整帖子。非常感谢。还有,这不是家庭作业。这是一个可能在我考试中出现的问题。好吧,抱歉假设。我已经编辑了我的答案,以包括我一起破解的解决方案,我希望它是清楚的!
> (elem-percent '())
'()
> (elem-percent (list 1 2 3 4 5))
'((1 . 20) (2 . 20) (3 . 20) (4 . 20) (5 . 20))
> (elem-percent (list 1 2 1 1))
'((1 . 75) (2 . 25))
> (elem-percent (list 1 2 1 1 2 3 3 4 4 4))
'((1 . 30) (2 . 20) (3 . 20) (4 . 30))