首页 > 解决方案 > 计算多个子列表方案中的元素数

问题描述

我想请您帮助我解决我正在尝试解决的任务。功能应该像这样工作。输入是子列表((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)

感谢您对此的帮助。简

标签: schemeracket

解决方案


在 Racket 中有一个内置的flatten程序,不需要重写它。再加上 good old 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))

推荐阅读