(define cart-product
(lambda (sos1 sos2)
(if (null? sos1) '()
(cons
(cart-prod-sexpr (car sos1) sos2)
(cart-product (cdr sos1) sos2)))))
(define cart-prod-sexpr
(lambda (s sos)
(if (null? sos) '()
(cons
(list s (car sos))
(cart-prod-sexpr s (cdr sos))))))
致电(cart-product '(q w) '(x y))
会产生(((q x) (q y)) ((w x) (w y)))
。
我如何才能生成((q x) (q y) (w x) (w y))
?
答案 0 :(得分:4)
胜利的高阶函数。 Haskell列表理解翻译成Scheme以获得更好的解决方案:
; cart xs ys = [ [x,y] | x <- xs, y <- ys ]
(define (cart xs ys)
(let ((f (lambda (x) (map (lambda (y) (list x y)) ys))))
(concatenate (map f xs))))
(cart '(a b c) '(x y)) => ((a x) (a y) (b x) (b y) (c x) (c y))
以m * n(m = | xs |,n = | ys |)运行。 concatenate来自SRFI-1。
答案 1 :(得分:2)
未测试。请注意,我定义的append-list
过程实际上返回以sos2
结尾的列表。这是合适的(也是正确的事),但不是一般的。
(define cart-product
(lambda (sos1 sos2)
(if (null? sos1) '()
(append-list
(cart-prod-sexpr (car sos1) sos2)
(cart-product (cdr sos1) sos2)))))
(define cart-prod-sexpr
(lambda (s sos)
(if (null? sos) '()
(cons
(list s (car sos))
(cart-prod-sexpr s (cdr sos))))))
(define append-list
(lambda (sos1 sos2)
(if (null? sos1) sos2
(cons
(car sos1)
(append-list (cdr sos1) sos2)))))
请注意,如果列表的大小为n,则需要时间O(n 3 )来生成大小为O的列表(n 2 )。 使用常规 我刚刚实现了常规append
代替O(n 4 )。append
而没有意识到。如果你想采取O(n 2 ),你必须更聪明。与此未经测试的代码一样。
(define cart-product
(lambda (sos1 sos2)
(let cart-product-finish
(lambda (list1-current list2-current answer-current)
(if (null? list2-current)
(if (null? list1-current)
answer-current
(cart-product-finish (car list1-current) sos2 answer-current))
(cart-product-finish list1-current (car sos2)
(cons (cons (cdr list1-current) (cdr list2-current)) answer-current))))
(cart-product-finish list1 '() '())))
如果我有错误,想法是递归循环遍历第一个和第二个元素的所有元素组合,每个元素用answer-current
替换cons
一个组合,然后是通过我们已经找到的其他一切。由于尾调用优化,这应该是有效的。
答案 2 :(得分:2)
脱离我的头顶:
(define cart-product
(lambda (sos1 sos2)
(if (null? sos1)
'()
(append
(cart-prod-sexpr (car sos1) sos2)
(cart-product (cdr sos1) sos2)))))
答案 3 :(得分:1)
(reduce #'append
(mapcar #'(lambda(x)
(mapcar #'(lambda(y)
(list x y))
'(a b c)))
'(1 2 3)))
=&GT; ((1 A) (1 B) (1 C) (2 A) (2 B) (2 C) (3 A) (3 B) (3 C))
[注意:解决方案适用于Common Lisp(CLisp)而不是Scheme,但我认为它在Scheme中应该非常相似]
外部(reduce#'append)用于替换(在knivil中解决的连接(map)
但是,与其他解决方案相比,我不确定我的解决方案是如何叠加性能参数的。有人可以对此发表评论吗?
答案 4 :(得分:1)
这是针对同一问题的不同解决方案。我认为这很容易理解,也许对某人有帮助。
(define (cart-product l1 l2)
(define (cart-product-helper l1 l2 org_l2)
(cond
((and (null? l1)) `())
((null? l2) (cart-product-helper (cdr l1) org_l2 org_l2))
(else (cons (cons (car l1) (car l2)) (cart-product-helper l1 (cdr l2) org_l2)))
)
)
(cart-product-helper l1 l2 l2)
)