2016-03-08 68 views
3

我想在方案(Gambit)中實現堆的算法。
我讀了他的論文並檢出了很多資源,但我還沒有找到許多功能語言實現。我想至少得到可能的組合數。
下一步將實際打印出所有可能的排列。在方案(排列生成)中實現堆算法

這是我到目前爲止有:

3 (define (heap lst n) 
    4 (if (= n 1) 
    5  0 
    6  (let ((i 1) (temp 0)) 
    7  (if (< i n) 
    8   (begin 
    9   (heap lst (- n 1)) 
10   (cond 
11    ; if even: 1 to n -1 consecutively cell selected 
12    ((= 0 (modulo n 2)) 
13    ;(cons (car lst) (heap (cdr lst) (length (cdr lst))))) 
14    (+ 1 (heap (cdr lst) (length (cdr lst))))) 
15 
16    ; if odd: first cell selectd 
17    ((= 1 (modulo n 2)) 
18    ;(cons (car lst) (heap (cdr lst) (length (cdr lst))))) 
19    (+ 1 (heap (car lst) 1))) 
20   ) 
21  ) 
22   0 
23  ) 
24 ) 
25 ) 
26) 
27 
28 (define myLst '(a b c)) 
29 
30 (display (heap myLst (length myLst))) 
31 (newline) 

我敢肯定,這是路要走,但它儘可能靠近我可以得到的。
任何幫助將是偉大的,謝謝。

回答

4

下面是在Wikipedia page上描述的算法的1對1轉錄。由於算法使用了大量的索引我已經使用了矢量數據結構,而不是一個列表:

(define (generate n A) 
    (cond 
    ((= n 1) (display A) 
      (newline)) 
    (else (let loop ((i 0)) 
       (generate (- n 1) A) 
       (if (even? n) 
        (swap A i (- n 1)) 
        (swap A 0 (- n 1))) 
       (if (< i (- n 2)) 
        (loop (+ i 1)) 
        (generate (- n 1) A)))))) 

swap助手程序:

(define (swap A i1 i2) 
    (let ((tmp (vector-ref A i1))) 
    (vector-set! A i1 (vector-ref A i2)) 
    (vector-set! A i2 tmp))) 

測試:

Gambit v4.8.4 

> (generate 3 (vector 'a 'b 'c)) 
#(a b c) 
#(b a c) 
#(c a b) 
#(a c b) 
#(b c a) 
#(c b a) 
+1

感謝您的解決方案! – RonanC