在方案中列出高效率的列表

时间:2013-01-10 17:21:28

标签: performance list recursion scheme racket

我想使用Scheme语言创建一个高效的特殊列表。 E.g:

  

功能名称:make-list
    参数:max
    (make-list max) -> (1 2 3 4 5 6 7 ... max)

我可以使用递归方法完成此任务。

#lang racket

(define (make-list max)
(define lst '())
(define count 1) 
(make-list-helper lst max count))

(define (make-list-helper lst max count) 
 (cond  
 [(> count max) lst]
 [else 
  (set! lst (append lst (list count))) 
  (make-list-helper lst max (add1 count)]))

但是,这种方法可以被认为是低的。我不知道如何提高列表的效率。有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:2)

关键原则是避免Schlemiel the Painter's algorithm,而不是append:随着列表变长,使用make-list-helper会反复占用越来越多。前面的元素是O(1),而附加是O(列表的长度);因此,让最里面的(max)返回单个列表cons,并使用{{1}}在递归上添加元素。

(我更喜欢迭代解决方案,但我是一个普通的lisper,所以我最好避免坚持任何的方案)。

不包含任何代码,以免损害您学习的乐趣。

答案 1 :(得分:2)

(define (make-list max)
  (let f ((i max)(a '()))
    (if (zero? i)
        a
        (f (- i 1) (cons i a)))))

这似乎是迭代的一个简单练习。

以上内容非常简单,您将在Scheme中的每个位置使用它。

确保您了解整个代码段的工作原理。

答案 2 :(得分:1)

“效率”的另一个定义可能是:用最少量的代码编写程序。考虑到这一点,问题的最短解决方案是使用现有程序来解决问题;例如,如果max = 10

(define (make-list max-val)
  (build-list max-val add1))

(make-list 10)
=> '(1 2 3 4 5 6 7 8 9 10)

以上内容使用了属于Racket的build-list程序:

  

按顺序将proc应用于0(sub1 n)的整数,创建n个元素的列表。如果lst是结果列表,则(list-ref lst i)(proc i)生成的值。

另一个选项,也适用于Racket,将使用iterations and comprehensions

(define (make-list max-val)
  (for/list ([i (in-range 1 (add1 max-val))]) i))

(make-list 10)
=> '(1 2 3 4 5 6 7 8 9 10)

无论哪种方式,鉴于程序是语言核心库的一部分,您可以确定它们的性能非常好,除非分析器表明它们是瓶颈,否则无需担心。