如何在Scheme中找到列表中重复字符的数量

时间:2013-11-29 17:10:39

标签: list scheme

我正在尝试在Scheme中创建一个函数,它返回一个字符在列表中重复的次数。 例如,如果我有(列表2 6'a'b'a'a 2) 结果必须是((2.2)(6.1)(a.3)(b.1))

它不需要以最有效的方式编写,只是想简单易懂,理解。

先谢谢你帮助我:)。

2 个答案:

答案 0 :(得分:1)

由于这似乎是作业,你没有发布任何代码,我们对你的约束和你目前对Scheme的了解一无所知,这很难回答。

基本上,您可以使用哈希映射有效地执行此操作,或使用2个嵌套循环效率较低。我会解释后者让你开始。

我假设您知道如何遍历列表。

所以基本上你需要

  • 1)遍历您的列表
    • 2)列表的每个元素(让我们称之为e)
      • 3)再次循环列表,计算你发现的(e)中有多少
      • 4)汇编(e)和计算循环的结果

步骤4)的结果需要在结果列表中组合。

如果这样做,结果将类似于

'((2 . 2) (6 . 1) (a . 3) (b . 1) (a . 3) (a . 3) (2 . 2))

这很接近......但不正确,因为你计算了几次元素。

因此,除了上述内容之外,您还需要一种跟踪已遇到的每个元素的方法,并且只有遇到新元素时才需要执行步骤3)和4)。保持跟踪可以通过另一个列表,或者只是通过检查您当前的结果列表,具体取决于您的代码。

如果您要显示任何代码,请更新您的问题,我们可以提供更多帮助。

修改

好的,既然GoZoner发布了代码,我有2个替代版本。我希望你研究所有这些并构成自己的想法,而不是简单地复制一个。

首先,我描述的版本;与GoZoner的版本相反,它不使用 mutable 列表,但比可变版本慢:

(define (how-many lst)
  (let loop ((lst2 lst) (res '()))
    (if (empty? lst2)
        (reverse res)
        (let ((c (car lst2)))
          (loop (cdr lst2) 
                (if (assoc c res) 
                    res 
                    (cons (cons c (count (lambda (e) (eq? e c)) lst)) res)))))))

=> '((2 . 2) (6 . 1) (a . 3) (b . 1))

如果你想使用一个可变结构(我也愿意),我建议使用可变的哈希表。以下示例在Racket中,但如果需要,可以轻松适应R6RS Scheme hash tables

(define (how-many lst)
  (let ((res (make-hash)))
    (for-each (lambda (e) (hash-update! res e add1 0)) lst)
    (hash->list res)))

=> '((6 . 1) (a . 3) (b . 1) (2 . 2))

请注意,哈希表不遵循顺序,因此您将得到相同的结果,但这些对可能会以不同的顺序(甚至从一次调用到下一次调用都不同)。

答案 1 :(得分:-1)

这样的事情:

(define (character-count list)
  (assert (list? list))
  (let looking ((list list) (rslt '()))
    (cond ((null? list) rslt)
          ((assoc (car list) rslt) =>
           (lambda (pair) 
             (set-cdr! pair (+ 1 (cdr pair)))
             (looking (cdr list) rslt)))
          (else (looking (cdr list) 
                         (cons (cons (car list) 1) rslt))))))
> (character-count '(2 a 2 a b c 2))
((c . 1) (b . 1) (a . 2) (2 . 3))

我得到'A'?!