请求实现Racket与ML版count_by_cat函数,解决列表操作难题
实现count_by_cat函数的Racket和ML方案
(a) Racket 实现
Racket中访问嵌套列表元素常用*first(取列表首元素)和second*(取列表第二个元素),对于空列表递归终止即可。下面提供两种实现方式:
递归版本
(define (count_by_cat lst) (cond ; 空列表返回初始累加值(0 0) [(empty? lst) '(0 0)] [else (let* ([current (first lst)] [key (first current)] [val (second current)] [rest-result (count_by_cat (rest lst))]) (cond [(= key 0) (list (+ (first rest-result) val) (second rest-result))] [(= key 1) (list (first rest-result) (+ (second rest-result) val))]))]))
- 逻辑说明:每次取出当前嵌套列表的key和value,递归处理剩余列表得到结果后,根据key将value累加到对应位置。
更简洁的foldl版本
(define (count_by_cat lst) (foldl (lambda (current acc) (let ([key (first current)] [val (second current)]) (if (= key 0) (list (+ (first acc) val) (second acc)) (list (first acc) (+ (second acc) val))))) '(0 0) lst))
- 逻辑说明:用*
foldl*遍历列表,初始累加器是'(0 0),每次迭代根据key更新累加器对应位置的值。
测试示例:
(count_by_cat '((0 1) (1 2) (1 3) (0 4) (0 3))) ; 返回 '(8 5)
(b) ML 实现
ML没有内置filter函数,我们可以用递归或*foldl*实现,这里结合模式匹配和递归处理:
递归版本(适配嵌套列表输入)
fun count_by_cat [] = [0, 0] | count_by_cat (current::rest) = let val key = hd current val v = hd (tl current) val [sum0, sum1] = count_by_cat rest in if key = 0 then [sum0 + v, sum1] else [sum0, sum1 + v] end;
- 逻辑说明:通过递归遍历列表,用*
hd取嵌套列表的key,hd (tl current)*取value,根据key值累加对应总和。
结合foldl的版本
fun count_by_cat lst = foldl (fn (current, acc) => let val key = hd current val v = hd (tl current) val sum0 = hd acc val sum1 = hd (tl acc) in if key = 0 then [sum0 + v, sum1] else [sum0, sum1 + v] end) [0, 0] lst;
- 逻辑说明:用*
foldl*遍历列表,初始累加器为[0,0],每次取出当前嵌套列表的key和value,更新累加器对应值。
测试示例:
count_by_cat [[0,1], [1,2], [1,3], [0,4], [0,3]]; (* 返回 [8,5] *)
内容的提问来源于stack exchange,提问作者Shrijan Reddy
相关产品推荐
相关产品推荐

