Scheme 在迭代期间从条件创建列表
我已经写了一个简单的程序来寻找一个数字的除数(不包括数字本身)。我已经知道了如何打印它们,但是我想让这个函数返回一个包含每个除数的列表Scheme 在迭代期间从条件创建列表,scheme,Scheme,我已经写了一个简单的程序来寻找一个数字的除数(不包括数字本身)。我已经知道了如何打印它们,但是我想让这个函数返回一个包含每个除数的列表 (define (divisors n) (do ((i 1 (+ i 1))) ((> i (floor (/ n 2)))) (cond ((= (modulo n i) 0) (printf "~a " i))))) 我的想法是创建一个本地列表,将元素添加到printf表达式所在的位置,然后
(define (divisors n)
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond
((= (modulo n i) 0)
(printf "~a " i)))))
我的想法是创建一个本地列表,将元素添加到printf表达式所在的位置,然后让函数返回该列表。我该怎么做呢?我是Scheme和Lisp的新手。您一定要使用吗?这里有一个方法:
(define (divisors n)
(do ((i 1 (add1 i))
(acc '() (if (zero? (modulo n i)) (cons i acc) acc)))
((> i (floor (/ n 2)))
(reverse acc))))
但我相信,如果您建立一个带有以下内容的输出列表,则更容易理解:
或者,如果您碰巧使用球拍,您可以这样使用:
(define (divisors n)
(reverse
(for/fold ([acc '()])
([i (in-range 1 (add1 (floor (/ n 2))))])
(if (zero? (modulo n i))
(cons i acc)
acc))))
请注意,以上所有解决方案都是以函数式编程风格编写的,这是在Scheme中编程的惯用方式,而不使用变异操作。也可以编写一个过程式的解决方案(参见@GoZoner的答案),类似于用类似C的语言解决这个问题,但这不是惯用的方法。只需创建一个局部变量
l
,并扩展它,而不是打印内容。完成后,将其返回。像这样:
(define (divisors n)
(let ((l '()))
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond ((= (modulo n i) 0)
(set! l (cons i l))))
l))
请注意,由于每个i
都“consed”在l
的前面,因此l
中的顺序将从高到低。如果需要从低到高的顺序,则使用(反向l)
作为返回值
(define (divisors n)
(let ((l '()))
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond ((= (modulo n i) 0)
(set! l (cons i l))))
l))