未经测试。请注意,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 2 ) 的列表将花费时间 O(n 3 )。 使用常规将采用 O(n 4 ) 代替。我只是在没有意识到的情况下实施了常规。 如果你想取 O(n 2 ) 你必须更聪明。就像在这个未经测试的代码中一样。append
append
(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
然后是我们已经找到的所有其他组合。由于尾部调用优化,这应该是有效的。