【发布时间】:2015-12-12 18:09:33
【问题描述】:
所以我有一个这样的元素示例列表
(define A (list 'a 'c 'd 'e 'f 'e 'a))
现在我想从这个样本中进行排名
(define (scan lst)
(foldl (lambda (element a-hash) (hash-update a-hash element add1 0))
(hash)
lst))
结果应该是这样的:
> #(('a . 2) ('f . 1) ('e . 2) ....)
因为 `scan 函数会生成一个包含唯一键和该键重复次数的哈希表(如果它捕获到一个未索引的键,它将为该新键创建一个新位置,从 0 开始计数)。
然后我想对该哈希表进行排序,因为它未排序:
(define (rank A)
(define ranking (scan A))
(sort ranking > #:key cdr)))
所以结果应该是这样的:
#(('a . 2) ('e . 2) ('f . 1) ...)
现在我想截断哈希表并在 n = 1 的阈值处丢弃底部(也就是只取重复次数超过 2 次的元素)。
(define (truncate lst n)
(define l (length lst))
(define how-many-to-take
(for/list
([i l]
#:when (> (cdr (list-ref lst i))
n))
i))
(take lst (length how-many-to-take)))
所以结果可能如下所示:
(('a.2)('e.2))
但是,在大范围内,这个过程效率不高,耗时太长。您对提高性能有什么建议吗?
非常感谢,
第 2 部分:
我有这个数据结构:
(automaton x
(vector (state y (vector a b c))
(state y (vector a b c)) ...))
然后我随机生成 1000 个人口。然后我使用上述功能对它们进行扫描和排名。如果我只是按原样扫描它们,那已经需要很长时间了。如果我尝试将它们展平成这样的列表
(list x y a b c y a b c...)
这需要更多的时间。这是扁平化功能:
(define (flatten-au au)
(match-define (automaton x states) au)
(define l (vector-length states))
(define body
(for/list ([i (in-range l)])
(match-define (state y z) (vector-ref states i))
(list y (vector->list z))))
(flatten (list x body)))
扫描功能看起来会有些不同:
(define (scan population)
(foldl (lambda (auto a-hash) (hash-update a-hash (flatten-automaton auto) add1 0))
(hash)
population))
【问题讨论】:
标签: sorting hash scheme racket fold