构建列表的替代方法,直到谓词满足为止?

时间:2016-07-21 15:09:39

标签: lisp racket

这是我建立斐波那契序列作为列表的方式,其值不超过 x

(define (fibs-upto x)
  (for/list ([i (in-naturals)]
             #:break (> (fib i) x))
            (fib i)))

在不使用#:break而不使用#lang lazy构建无限懒惰列表的情况下,是否有另一种更简洁的方法可以做到这一点?

3 个答案:

答案 0 :(得分:2)

这是一个只评估(fib i)一次的解决方案。

(define (fibs-upto x)
  (for*/list ([i     (in-naturals)]
              [fib-i (in-value (fib i))]
              #:break (> fib-i x))
    fib-i))

但是阅读标准循环可能更容易:

(define (fibs-upto x)
  (define (loop i)
    (define fib-i (fib i))
    (if (> fib-i x)
        '()
        (cons fib-i (loop (+ i 1)))))
  (loop 0))

也就是说,fib将先前计算出的上述解决方案的值缓存为O(n)非常重要。

更新

使用sequence-map的版本:

(define (fibs-upto x)
  (for/list ([y (sequence-map fib (in-naturals))]
             #:break (> y x))
    y))

答案 1 :(得分:1)

如果您只想要斐波那契数字列表,您可以例如。

(define (fib-upto limit)
  (let loop ([fibs '(1 1)])
    (let ((fn (+ (first fibs) (second fibs))))
      (if (> fn limit)
          (reverse fibs)
          (loop (cons fn fibs))))))
;; e.g.:
(fib-upto 100)
'(1 1 2 3 5 8 13 21 34 55 89)

如果您想了解一些建立具有停止条件的列表的惯用方法,请查看展开(或展开 - 右边虽然您希望展开) - http://srfi.schemers.org/srfi-1/srfi-1.html#FoldUnfoldMap

答案 2 :(得分:0)

因为你在球拍中发布了​​这个...这可能是问题的解决方案,但我确实改变了它的一部分,如果这是一个问题,这很容易解决。我希望这有帮助

// i =开始的数字,x =要达到的数字

x ^= y ^= x ^= y;

解决方法

(define (fibs-upto i x)
  (cond
    [(> (fib i) x) empty]
    [else (cons (fib i)(fibs-upto (+ i 1) x))]))