【问题标题】:infinite sequence scheme to make infinite sequence无限序列方案制作无限序列
【发布时间】:2017-05-19 20:25:56
【问题描述】:

我有一个计划中的项目,我需要在其中实现无限的数字序列。我不能使用任何方案内置的复杂函数,我只是不知道如何使我的序列无限,而程序不会在无限循环中崩溃。我不必真正输出它,但我需要能够使用它。

(seq n)   ;;output: n,n+1,n+2,n+3.... to infinity (seq 5) ->5,6,7,8,9...

现在我做了一个序列直到 n+7,但我需要这个到无穷大:

(define (seq n)
   (define (asc-order LIST counter)
     (cond ((= counter (+ n 7)) LIST)
           (else (asc-order (append LIST (cons (+ counter 1) '()))  
           (+ counter 1)))))
(asc-order '() (- n 1))
)

IO 示例(它有效,但我需要它无限序列):

>(define s (seq 3)) 
>(car s)   
3

【问题讨论】:

    标签: list recursion scheme racket infinite-sequence


    【解决方案1】:

    您可以将无限序列表示为一次生成一个元素的函数。然后,用户(消费者)可以调用该函数,每个需要序列的新元素。

    一个例子:

    (define (f x) (* x x))
    
    (define seq
      (let ()
        (define n 0)        ; current index
        (lambda ()          ; the function that is to be called repeatedly
          (define a (f n))  ;   compute the new element
          (set! n (+ n 1))  ;   compute new index
          a)))              ;   return the new element
    
    (seq)  ; compute element 0
    (seq)  ; compute element 1
    (seq)  ; ...
    (seq)
    (seq)
    (seq)
    

    计算结果为:

    0
    1
    4
    9
    16
    25
    

    为了编写 (sequence->list s n) 来计算序列 s 的第一个 n 元素,请创建一个循环调用 s 总共 n 次 - 并将结果收集到一个列表中。

    【讨论】:

    • 感谢@soegaard,但正如我提到的,我不允许使用内置的非原始函数,特别是设置!
    【解决方案2】:

    这是另一个使用延迟评估的解决方案:

    (use-modules (ice-9 receive))
    
    
    (define (seq f)
      (let loop ((n 0))
        (lambda ()
          (values (f n) (loop (1+ n))))))
    
    
    (define squares (seq (lambda (x) (* x x))))
    
    (receive (square next) (squares)
      (pk square) ;; => 0
      (receive (square next) (next)
        (pk square) ;; => 1
        (receive (square next) (next)
          (pk square) ;; => 4
          (receive (square next) (next)
            (pk square))))) ;; => 9
    

    【讨论】:

      【解决方案3】:

      关键是通过围绕它包装一个过程来延迟对列表的评估。

      这是我能想到的最简单的实现。
      它只是在尾巴上“懒惰”。

      (define (seq n)
        (cons n (lambda () (seq (+ n 1)))))
      
      (define (seq-car s)
        (car s))
      
      (define (seq-cdr s)
        ((cdr s)))
      

      使用示例:

      ; Get the 'n' first elements of 's'.
      (define (seq-take n s)
        (if (<= n 0)
            '()
            (cons (seq-car s) (seq-take (- n 1) (seq-cdr s)))))
      
      
      > (define s (seq 10))
      > s
      '(10 . #<procedure>)
      > (seq-take 5 s)
      '(10 11 12 13 14)
      

      【讨论】:

      • take 实现中的一个常见错误是过度生产 1。对于 n=1,不需要强制尾部,这也可能发散。 :)
      猜你喜欢
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 2014-07-19
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多