好的,我想计算每个[数字]在使用Scheme的列表中出现的次数。
我该怎么做?我还想存储给定数字的计数器并重新构建一个新列表。
例如,我有以下列表((1 2)(2 5)(5 7)(7 8)(6 8)(4 6)(3 4)(1 3)(4 8))
我在考虑先将列表弄平,然后为每个数字设置一个计数器(不知道该怎么做)。然后重新构建与原始编号对应的新列表。 (这可能很棘手?我需要存储一个临时变量?)
从这个例子说,数字1出现两次,数字2出现两次,数字3出现两次等...所以我想重新创建一个新列表,如下所示:
(1 2) (2 2) (3 2) (4 3) (5 2) (7 2) (6 2) (8 3)
任何想法我怎么能做到这一点?
更新
我正在考虑实现这样的增量计数器助手吗?
(define inc-counter
(let ((counter 0))
(lambda () (set! counter (+ counter 1)))))
答案 0 :(得分:3)
好答案主要取决于您的实施(模数R6RS)。在PLT方案的情况下,这是一个快速定义。它避免了扁平化列表 - 您只需要扫描每个项目,因此在扫描树时如此简单,构建新副本毫无意义。此外,此函数对结果列表进行排序(因为它将在离开哈希表的过程中全部加扰)。即使您使用的是一些完全不同的实现,也应该很容易翻译:
(define (counts x)
(define t (make-hash))
(define (scan x)
(if (list? x)
(for-each scan x)
(hash-set! t x (add1 (hash-ref t x 0)))))
(scan x)
(sort (hash-map t list) < #:key car))
(注意,顺便说一句,如果这是任何一种硬件问题,那么这段代码太实用了,无法作为答案...)
答案 1 :(得分:1)
使用accumulator参数展平,该参数保留每个参数列表的关联列表。这样你就可以获得每次循环所需的所有数据。
例如,您可以像这样编写阶乘:
(define (factorial num accum)
(if (= num 0) accum (factorial (- num 1) (* accum num)))
并用(factorial 10 1)调用它。最后,累加器的值是函数的结果。在您的示例中,您将编写一个小帮助函数,该函数将调用flatten并跟踪每个数字出现的次数。
答案 2 :(得分:0)
也许不是最有效的解决方案,但我认为你可以通过partition
列表的第一个元素来实现这一点,直到列表中没有更多的元素。然后,元素列表将是列表中与第一个数字相同的所有数字。可以在out-elements列表上重复此过程,直到列表中没有更多元素为止。
答案 3 :(得分:0)
您可以使用哈希表将数字映射到其出现次数。使用(make-hash)
创建它。