计算所有可能的列表组合的递归函数的示例是什么?例如,(combine (list 1 2 3) (list 1 2))
应该返回'((1 1) (1 2) (2 1) (2 2) (3 1) (3 2))
.
这是我的看法;我首先定义一个助手concat/map
,它需要一个列表和一个函数。像普通的一样map
,它将该函数应用于列表中的每个元素。不像map
,不过,它使用append
合并结果而不是cons
。这很有用,因为我们想要返回单层列表作为答案:
(define concat/map
(lambda (ls f)
(cond
[(null? ls) '()]
[else (append (f (car ls)) (concat/map (cdr ls) f))])))
然后,写combine
对于两个列表来说很简单。您获取第一个列表的每个元素,然后将其与一个元素结合起来制作每个列表x
从第二个列表中。由于这会返回第一个列表中每个元素的答案列表,因此请使用concat/map
按照我们想要的方式将其组合在一起:
(define combine
(lambda (xs ys)
(concat/map xs (lambda (x)
(map (lambda (y) (list x y)) ys)))))
的版本combine
对一个或多个列表进行操作,我们称之为combine*
,有点棘手。而不是将所有列表组合起来x
对于第二个列表中的元素,我们只需递归地求所有剩余元素的乘积ys
, 进而cons
x
到每一个结果上。当只有两个列表要组合时,递归停止,并使用原始列表combine
在这种情况下。
(define combine*
(lambda (xs . ys*)
(cond
[(null? ys*) (map list xs)]
[(null? (cdr ys*)) (combine xs (car ys*))]
[else (concat/map xs (lambda (x)
(map (lambda (y) (cons x y))
(apply combine* ys*))))])))
作为奖励,这种使用模式concat/map
做一些工作并结合得到的答案实际上是列表单子。这里虽然简化了,但是结构已经就位了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)