2013-10-24 84 views
1

我寫一個Clojure的遞歸函數,以便給出:- 缺少一個支架

(luty [1 2 3 4]) 

應該有輸出是這樣的:

((1 2 3 4) (2 3 4) (3 4) (4)() 

我的代碼是:

(defn luty [a1] 
(if (empty? a1) 
    (list) 
    (cons (seq a1) (luty (rest a1)) 
))) 

我得到輸出:

((1 2 3 4) (2 3 4) (3 4) (4)) //comment missing a() 

有人可以建議我哪裏出錯嗎?

回答

2

如果我們打印出來的過程,並在第二個看過去opperation:

user> (defn luty [a1] 
     (println "a1 is" a1) 
     (if (empty? a1) 
      () 
      (cons (seq a1) (luty (rest a1))))) 
#'user/luty 
user> (luty [1 2 3 4]) 
a1 is [1 2 3 4] 
a1 is (2 3 4) 
a1 is (3 4) 
a1 is (4) 
a1 is() 
((1 2 3 4) (2 3 4) (3 4) (4)) 
user> (cons '(4)()) 
((4)) 

我們可以看到,添加(4)爲空列表的結果是((4)),而不是((4)())因爲你很可能想。這可以通過使基情況下,包含空列表的列表是固定的,而不是僅僅一個空列表

user> (defn luty [a1] 
     (if (empty? a1) 
      '(()) 
      (cons (seq a1) (luty (rest a1))))) 
#'user/luty 
user> (luty [1 2 3 4]) 
((1 2 3 4) (2 3 4) (3 4) (4)()) 
1

缺點的返回值與作爲第一元件的第一個參數和的其餘部分的列表作爲第二個參數的列表。如果第二個參數爲空或零,則表示您將第一個參數作爲單個成員。

其原因在於列表(概念上至少在clojure中)鏈接列表與雙空間單元格;頭元素的一個指針和尾的一個指針(另一個列表,在clojure中保證是一個seq類的東西 - 在許多其他的lisps中,你可以將第二個指針設置爲你想要的任何值,所以你不是保證從那裏獲得一個「適當」名單)。 「尾部」位置的零位表示列表的結尾。

列表是最容易實現和可理解的持久性(以不變的結構共享的clojure含義)數據結構。

1

只給你看它用不同的方式:

user> (defn luty [a1] 
     (reductions (fn [c _] (rest c)) (or (seq a1) '()) (-> a1 count range))) 
    => #'user/luty 
user> (luty [1 2 3 4]) 
    => ((1 2 3 4) (2 3 4) (3 4) (4)()) 
user> (luty []) 
    => (()) 
user> (luty nil) 
    => (())