在满足谓词之前构建列表的替代方法?
Alternative way to build a list until predicate is satisfied?
这是我构建斐波那契数列的方法,其值不超过 x:
(define (fibs-upto x)
(for/list ([i (in-naturals)]
#:break (> (fib i) x))
(fib i)))
是否有另一种更简洁的方法可以在不使用 #:break
且不使用 #lang lazy
来构建无限懒惰列表的情况下执行此操作?
这里是 (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))
由于您在 racket 中发布了此内容...这可能是解决问题的方法,但我确实更改了其中的一部分,如果出现问题则很容易解决。希望对您有所帮助
// i = 开始的数字,x = 上升到的数字
(define (fibs-upto i x)
(cond
[(> (fib i) x) empty]
[else (cons (fib i)(fibs-upto (+ i 1) x))]))
解决方法
(define (fibs-upto x)
(fibs-help 0 x))
(define (fibs-help i x)
(cond
[(> (fib i) x) empty]
[else (cons (fib i)(fibs-help (+ i 1) x))]))
如果您只想要斐波那契数列,您可以例如
(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)
如果您想了解一些使用停止条件构建列表的惯用方法,请查看展开(或展开-right,尽管您更愿意展开)-- http://srfi.schemers.org/srfi-1/srfi-1.html#FoldUnfoldMap
这是我构建斐波那契数列的方法,其值不超过 x:
(define (fibs-upto x)
(for/list ([i (in-naturals)]
#:break (> (fib i) x))
(fib i)))
是否有另一种更简洁的方法可以在不使用 #:break
且不使用 #lang lazy
来构建无限懒惰列表的情况下执行此操作?
这里是 (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))
由于您在 racket 中发布了此内容...这可能是解决问题的方法,但我确实更改了其中的一部分,如果出现问题则很容易解决。希望对您有所帮助
// i = 开始的数字,x = 上升到的数字
(define (fibs-upto i x)
(cond
[(> (fib i) x) empty]
[else (cons (fib i)(fibs-upto (+ i 1) x))]))
解决方法
(define (fibs-upto x)
(fibs-help 0 x))
(define (fibs-help i x)
(cond
[(> (fib i) x) empty]
[else (cons (fib i)(fibs-help (+ i 1) x))]))
如果您只想要斐波那契数列,您可以例如
(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)
如果您想了解一些使用停止条件构建列表的惯用方法,请查看展开(或展开-right,尽管您更愿意展开)-- http://srfi.schemers.org/srfi-1/srfi-1.html#FoldUnfoldMap