2011-11-26 66 views
0

尋找會做一個類似於下面的函數:建立一個二維表

(foo 3 2) => '(((1 1) (1 2) (1 3)) 
        ((2 1) (2 2) (2 3))) 

會不會有在DrRacket任何內置函數,實現了嗎?

+0

很難說出你想要的功能。嵌套列表如何工作超過2個參數? – Cam

回答

0

代碼:

(define (foo-makey const max data) 
    (let* ((i (length data)) 
     (newy (- max i)) 
     (newpair (cons const newy))) 
    (if (= max i) 
     data 
     (foo-makey const max 
        (cons newpair data))))) 

(define (foo-makex xmax ymax data) 
    (let* ((i (length data)) 
     (newx (- xmax i)))   
    (if (= xmax i) 
     data 
     (foo-makex xmax ymax 
        (cons (foo-makey newx ymax '()) data))))) 

(define (foo x y) 
    (foo-makex y x '())) 

輸出:

> (foo 3 2) 
'(((1 . 1) (1 . 2) (1 . 3)) ((2 . 1) (2 . 2) (2 . 3))) 
0

我不能回答你的問題是,是因爲我不明白的嵌套列表應該如何爲> 2點的參數工作。 AFAIK沒有內置的功能來做你想做的事情。

爲了開始您的工作,下面是一些代碼,可生成輸出而不包含嵌套列表。作爲練習,請嘗試調整代碼以執行嵌套列表。看看有沒有辦法讓代碼更高效。

;;can take in any number of arguments 
(define (permutations . nums) 
    (foldl 
    (lambda (current-num acc) 
    (append-map 
     (lambda (list-in-acc) 
     (for/list ((i (build-list current-num (curry + 1)))) 
      (append list-in-acc (list i)))) 
     acc)) 
    (list (list)) 
    (reverse nums))) 

例1:

> (permutations 3 2) 
'((1 1) (1 2) (1 3) (2 1) (2 2) (2 3)) 

例2:

> (permutations 10) 
'((1) (2) (3) (4) (5) (6) (7) (8) (9) (10)) 

例3:

> (permutations 2 3 4) 
'((1 1 1) 
    (1 1 2) 
    (1 2 1) 
    (1 2 2) 
    (1 3 1) 
    (1 3 2) 
    (2 1 1) 
    (2 1 2) 
    (2 2 1) 
    (2 2 2) 
    (2 3 1) 
    (2 3 2) 
    (3 1 1) 
    (3 1 2) 
    (3 2 1) 
    (3 2 2) 
    (3 3 1) 
    (3 3 2) 
    (4 1 1) 
    (4 1 2) 
    (4 2 1) 
    (4 2 2) 
    (4 3 1) 
    (4 3 2)) 
5

要使用獲得這樣的事情的主要工具球拍是各種for循環。假設你想創建一個基於列表的矩陣結構,那麼這是得到它的一種方法:

#lang racket 
(define (foo x y) 
    (for/list ([i y]) 
    (for/list ([j x]) 
     (list (add1 i) (add1 j))))) 

而且因爲人們提出瞭如何使foo創建任何尺寸的矩陣更普遍的問題,這裏的與任意數量的參數工作,並仍然是一個廣義的版本,返回時被稱爲(foo 3 2)相同的結果:

#lang racket 
(define (foo . xs) 
    (let loop ([xs (reverse xs)] [r '()]) 
    (if (null? xs) 
     (reverse r) 
     (for/list ([i (car xs)]) 
     (loop (cdr xs) (cons (add1 i) r)))))) 

(注順便說一句,在這兩種情況下,我用一個簡單的基於0的迭代去,並用add1來得到你想要的數字另一種方法是替換

(for/list ([i x]) ... (add1 i) ...) 

(for/list ([i (in-range 1 (add1 x)]) ... i ...) 

+0

非常酷。謝謝! – David

+0

請注意,第一個代碼片段可以使用'for */list'。另外,在你的括號內,我認爲你的意思是'y',而不是'x'。 –

+0

不,你不能使用'for */list',因爲那樣會產生一個扁平的對子列表,而原來的問題需要像列表結果這樣的矩陣。而在括號中,我的意思是可以對任何'x'和'i'元變量進行轉換 - 我只是不想冗餘地重複整個事情。 –

0

(定義(生成-2D排列) (生成列表行(拉姆達(X)(構建列表欄(拉姆達(y)的(list(+ x 1)(+ y 1))))))