如何使用Scheme为列表中的每个数字实现一个计数器?
好的,我想使用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)))))
Okay I want to count the number of times each [number] has appeared inside a list using Scheme.
How can I do that ? I also would like to store the counter of the given number and re-construct a new list.
For example I have the following list ((1 2)(2 5)(5 7)(7 8)(6 8)(4 6)(3 4)(1 3)(4 8))
I was thinking first flatten the list, and then set a counter for each number (don't know how to do it). And then reconstruct a new list corresponding to the original number. (this can be tricky ? I need to store a temporary variable ?)
Say from this example the number 1 appeared twice, number 2 appeared twice, number 3 twice etc... so I would like to recreate a new list to something like this:
(1 2) (2 2) (3 2) (4 3) (5 2) (7 2) (6 2) (8 3)
any idea how I can achieve this ?
Update:
I was thinking to implement an increment counter helper something like this ?
(define inc-counter
(let ((counter 0))
(lambda () (set! counter (+ counter 1)))))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好的答案主要取决于您的实现(模 R6RS)。对于 PLT 方案,这里有一个快速定义来实现这一点。它避免了扁平化列表 - 您只需要扫描每个项目,因此当扫描树如此简单时构建新副本是没有意义的。此外,该函数还会对结果列表进行排序(因为它在从哈希表中出来时会被打乱)。即使您使用一些完全不同的实现,它也应该很容易翻译:(
请注意,顺便说一句,如果这是任何类型的硬件问题,那么这段代码太实用了,无法用作答案......)
A good answer mostly depends on your implementation (modulo R6RS). In the case of PLT scheme, here's a quick definition that does that. It avoids flattening the list -- you only need to scan each item, so there's no point in constructing a new copy when scanning a tree is so simple. Also, this function sorts the resulting list (since it will be all scrambled on its way out of the hash table). Even if you're using some completely different implementation, it should be easy to translate:
(Note, BTW, that if this is any kind of HW question, then this code is much too practical to be useful as an answer...)
使用累加器参数进行展平,以保留每个出现次数的关联列表。这样您每次循环都会获得所需的所有数据。
例如,您可以这样编写阶乘:
(定义(阶乘数字累加)
(if (= num 0) Accum (阶乘 (- num 1) (* Accum num)))
并用 (factorial 10 1) 来调用它。最后,累加器的值就是函数的结果。在您的示例中,您将编写一个小辅助函数,该函数将调用 flatten 并跟踪每个数字出现的次数。
Use an accumulator parameter to flatten which keeps an association list of how many times each has appeared. That way you'll have all the data you need each time around the loop.
For example, you might write factorial like this:
(define (factorial num accum)
(if (= num 0) accum (factorial (- num 1) (* accum num)))
And call it with (factorial 10 1). At the end, the value of the accumulator is the result of the function. In your example, you'd write a little helper function that would call flatten and keep track of the number of times each number has appeared.
也许不是最有效的解决方案,但我认为您可以通过按第一个元素对列表进行分区来实现此目的,直到列表中不再有元素为止。那么,内元素列表将是列表中与第一个数字相同的所有数字。可以在出元素列表上重复此过程,直到列表中不再有元素为止。
Perhaps not the most efficient solution, but I think you could achieve this by
partition
ing the list by its first element until there are no more elements in the list. The list of in-elements would then be all of the numbers in the list that were the same as the first number. This process could be repeated on the list of out-elements until there were no more elements in the list.您可以使用哈希表将数字映射到其出现次数。使用
(make-hash)
创建它。You could use a hashtable mapping the number to its number of occurrences. Create it with
(make-hash)
.