【问题标题】:make a list in scheme with high efficiency高效的在方案中列出清单
【发布时间】:2012-12-25 04:13:49
【问题描述】:

我想用Scheme语言高效地创建一个特殊的列表。例如:

函数名称: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)]))

但是,这种方法可以认为是低级的。我不知道如何提高其制作清单的效率。谁能帮帮我?

【问题讨论】:

  • 我知道它可能不适用于你的情况,但你可以看看 Lazy Racket,因为在真正需要它们之前不必构建这些列表。跨度>
  • 顺便说一句,没有充分的理由在您的代码中使用 set!

标签: performance list recursion scheme racket


【解决方案1】:

关键原则是避免使用Schlemiel the Painter's algorithm,而您不会这样做:随着列表变长,重复使用append 会花费越来越多的时间。前置元素是O(1),而附加是O(列表长度);所以让最里面的make-list-helper 返回一个单数列表(max),并使用cons 在递归前添加元素。

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

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

【讨论】:

  • 谢谢!我会试试这个方法! :-)
【解决方案2】:
(define (make-list max)
  (let f ((i max)(a '()))
    (if (zero? i)
        a
        (f (- i 1) (cons i a)))))

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

上面的内容非常简单,您将在 Scheme 的任何地方使用它。

确保您了解整个 sn-p 的工作原理。

【讨论】:

    【解决方案3】:

    “效率”的另一个定义可能是:用最少的代码编写过程。考虑到这一点,问题的最短解决方案是使用现有程序来解决问题;例如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)
    

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

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 2011-03-22
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 2014-06-08
      相关资源
      最近更新 更多