未テスト。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 '() '())))
バグがある場合に備えて、1 番目と 2 番目の要素のすべての組み合わせを再帰的にループし、それぞれanswer-current
を acons
に置き換えて、もう 1 つの組み合わせを使用し、その後に既に見つかった他のすべての要素が続くようにします。テールコール最適化のおかげで、これは効率的です。