我正在尝试在Scheme中创建一个函数,它返回一个字符在列表中重复的次数。 例如,如果我有(列表2 6'a'b'a'a 2) 结果必须是((2.2)(6.1)(a.3)(b.1))
它不需要以最有效的方式编写,只是想简单易懂,理解。
先谢谢你帮助我:)。
答案 0 :(得分:1)
由于这似乎是作业,你没有发布任何代码,我们对你的约束和你目前对Scheme的了解一无所知,这很难回答。
基本上,您可以使用哈希映射有效地执行此操作,或使用2个嵌套循环效率较低。我会解释后者让你开始。
我假设您知道如何遍历列表。
所以基本上你需要
步骤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'?!