我想在我要解决的任务上寻求帮助。函数应该像这样工作。输入是子列表((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
,输出应该是((1 . 3) (10 . 4) (250 . 4) (255 . 1))
,因此输出实际上是文本格式的直方图。
我将此代码与实现flatten
的功能配合使用,该功能由子列表组成一个列表。但这是在计算子列表的数量,而不是子列表中的每个元素。
(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-cnt cur-val) acc))))
(cons (cons cur-cnt cur-val) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
平铺功能:
(define (flatten lst)
(if (not (list? lst))
(list lst)
(apply append (map flatten lst))))
输出:
> (run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
(250 10 1 1 250 10 1 1 250 10 250 1 255 10 1 1)
感谢您的帮助。 扬
答案 0 :(得分:1)
在球拍中,有一个内置的flatten
过程,无需重写。再加上良好的旧bagify
,我们可以使用简单的过程组合来解决问题-您应该避免尝试在单个过程中完成所有操作,这会造成混乱:
#lang racket
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
(define (run-length-encode lst)
(hash->list
(bagify (flatten lst))))
它按预期工作:
(run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
=> '((1 . 3) (250 . 4) (10 . 4) (255 . 1))