2010-03-20 30 views
5

Tôi đã cố gắng thực hiện một chức năng trả về Sản phẩm Descartes của n bộ, trong Dr Scheme, các bộ được đưa ra như một danh sách các danh sách, tôi đã bị mắc kẹt ở đây cả ngày, tôi muốn một số hướng dẫn về nơi bắt đầu.Sản phẩm Descartes trong Đề án

---- EDIT SAU -----

Dưới đây là giải pháp tôi đưa ra, tôi chắc chắn rằng nó không phải đến nay là efficent nhất hoặc gọn gàng nhưng tôi chỉ studing Scheme cho 3 tuần nên dễ dàng với tôi.

+0

Đây có phải là bài tập về nhà không? –

+0

Tương tự: http://stackoverflow.com/questions/1658229/scheme-lisp-nested-loops-and-recursion –

+0

vâng, đó là một phần của bài tập về nhà, tôi không nhất thiết cần mã, tôi muốn một số hướng dẫn –

Trả lời

3
;returs a list wich looks like ((nr l[0]) (nr l[1])......) 
    (define cart-1(λ(l nr) 
     (if (null? l) 
      l 
      (append (list (list nr (car l))) (cart-1 (cdr l) nr))))) 

;Cartesian product for 2 lists 
(define cart-2(λ(l1 l2) 
       (if(null? l2) 
      '() 
      (append (cart-1 l1 (car l2)) (cart-2 l1 (cdr l2)))))) 

;flattens a list containg sublists 
(define flatten 
(λ(from) 
(cond [(null? from) from] 
     [(list? (car from)) (append (flatten (car from)) (flatten (cdr from)))] 
     [else (cons (car from) (flatten (cdr from)))])}) 

;applys flatten to every element of l 
(define flat 
(λ(l) 
(if(null? l) 
l 
(cons (flatten (car l)) (flat (cdr l)))))) 

;computes Cartesian product for a list of lists by applying cart-2 
(define cart 
(lambda (liste aux) 
(if (null? liste) 
    aux 
    (cart (cdr liste) (cart-2 (car liste) aux))))) 


(define (cart-n l) (flat (cart (cdr l) (car l)))) 
4
;compute the list of the (x,y) for y in l 
(define (pairs x l) 
    (define (aux accu x l) 
    (if (null? l) 
     accu 
     (let ((y (car l)) 
       (tail (cdr l))) 
      (aux (cons (cons x y) accu) x tail)))) 
    (aux '() x l)) 

(define (cartesian-product l m) 
    (define (aux accu l) 
    (if (null? l) 
     accu 
     (let ((x (car l)) 
       (tail (cdr l))) 
      (aux (append (pairs x m) accu) tail)))) 
    (aux '() l)) 

Nguồn: Scheme/Lisp nested loops and recursion

+1

cách thức Đây là sản phẩm Descartes của 2 bộ, câu hỏi của tôi là cho bộ n, tôi biết làm thế nào để tính toán nó cho hai bộ, tôi không biết làm thế nào để làm cho nó cho n –

+2

Kết hợp phiên bản 2 bộ với gấp để có phiên bản n-set. Nói chung cho các hoạt động liên kết, bạn có thể xác định một phiên bản đối số n theo các phiên bản đối số 2 với gấp. – soegaard

2

Đây là giải pháp đầu tiên của tôi (tối ưu):

#lang scheme 
(define (cartesian-product . lofl) 
    (define (cartOf2 l1 l2) 
    (foldl 
    (lambda (x res) 
     (append 
     (foldl 
     (lambda (y acc) (cons (cons x y) acc)) 
     '() l2) res)) 
    '() l1)) 
    (foldl cartOf2 (first lofl) (rest lofl))) 

(cartesian-product '(1 2) '(3 4) '(5 6)) 

Về cơ bản bạn muốn sản xuất các sản phẩm của các sản phẩm của các danh sách.

+0

Ngoài ra nếu bạn nhìn vào câu hỏi mà Yuval đăng Paul Hollingsworth đăng một phiên bản tài liệu tốt, mặc dù không làm việc trong chương trình plt. http://stackoverflow.com/questions/1658229/scheme-lisp-nested-loops-and-recursion/1677386#1677386 – Jake

+0

Về giải pháp của Cipher, bạn có thể làm gì để có được danh sách các danh sách được phát hiện? –

+1

Tôi nghĩ điều bạn muốn nói là bạn không muốn kết quả là danh sách các danh sách không đúng (hoặc các cặp lồng nhau), thay vào đó bạn muốn danh sách các danh sách. Nếu vậy, cách dễ nhất/đơn giản nhất/tồi tệ nhất để thực hiện điều này sẽ là thay đổi (khuyết x y) thành (khuyết x (nếu (danh sách y) y (danh sách y))). Tôi không thích điều này. Nhưng nó không phải là bài tập về nhà của tôi ...;) – Jake

6

Đây là triển khai ngắn gọn cũng được thiết kế để giảm thiểu kích thước của cấu trúc kết quả trong bộ nhớ, bằng cách chia sẻ đuôi của danh sách thành phần. Nó sử dụng SRFI-1.

(define (cartesian-product . lists) 
    (fold-right (lambda (xs ys) 
       (append-map (lambda (x) 
           (map (lambda (y) 
            (cons x y)) 
            ys)) 
          xs)) 
       '(()) 
       lists)) 
1

Tôi đã cố gắng thực hiện giải pháp thanh lịch của Mark H Weaver (https://stackoverflow.com/a/20591545/7666) dễ hiểu hơn.

import : srfi srfi-1 
define : cartesian-product . lists 
    define : product-of-two xs ys 
     define : cons-on-each-ys x 
      map : lambda (y) (cons x y) 
       . ys 
     append-map cons-on-each-ys 
        . xs 
    fold-right product-of-two '(()) lists 

Nó vẫn là cùng một logic, nhưng đặt tên cho các hoạt động.

Ở trên là trong wisp-syntax aka SRFI-119. Sơ đồ đồng bằng tương đương là:

(import (srfi srfi-1)) 
(define (cartesian-product . lists) 
    (define (product-of-two xs ys) 
     (define (cons-on-each-ys x) 
      (map (lambda (y) (cons x y)) 
       ys)) 
     (append-map cons-on-each-ys 
        xs)) 
    (fold-right product-of-two '(()) lists)) 
Các vấn đề liên quan