2011-11-07 61 views
1

下面是一個遞歸函數:遞歸函數失敗斷言

(defn make-control-data [it alphabet] 
    {:pre [(integer? it) (pos? it)]} 
    (let [shuffled-alphabet-string (reduce str (shuffle alphabet))] 
    (if (zero? it) 
     shuffled-alphabet-string 
     (str shuffled-alphabet-string (make-control-data (dec it) alphabet))))) 

應該採取的整數(it),指定數目的遞歸調用和字母串列表,例如,["a" "b"]。它應該使用字母表中的所有字母返回一個長度爲it*length(alphabet)的隨機排序字符串。如果it = 2和字母表= ["a" "b"]該函數應產生一個長度爲(* 2 (count ["a" "b"])) = 4的隨機字符串,使用字母表中的所有字母["a" "b"]

它打破了前提條件(pos? it),並返回一個長度爲(it+1)*length(alphabet)的字符串。

任何人都可以看到有什麼問題嗎?

+0

建議使用高階函數而不是顯式遞歸,如@amalloy – Ankur

回答

2

您的函數顯然願意接受it = 0,所以您的先決條件不應禁止該輸入。零是你的遞歸基本情況,而不是一個錯誤。如果我在這個功能上設置了一個先決條件(儘管我不這樣做),那將是[(not (neg? it))]

如果我是從頭開始編寫這個我不會與所有的遞歸噪聲打擾,只是簡單:

(defn make-control-data [num alphabet] 
    (apply str (repeatedly num #(apply str (shuffle alphabet))))) 
+0

的答案所示。另外,如上面的代碼所示,它是關閉的。 – cwallenpoole

+0

我看到,當它= 0時,(pos?it)返回false。謝謝。 –

+1

@sesanker是的,零不是正數。不過,這不是消極的。 [關於或指定數量大於零](http://www.thefreedictionary.com/positive) – amalloy

0

這是一個正確的函數使用遞歸:

(defn make-control-data [it alphabet] 
    {:pre [(integer? it) (not (neg? it))]} 
    (if (zero? it) "" 
     (str (reduce str (shuffle alphabet)) (make-control-data (dec it) alphabet)))) 

(make-control-data 2 ["a" "b" "c"])回報"bcacab"

(count (make-control-data 2 ["a" "b" "c"]))返回6.

此外,以下幾項工作:

(defn make-control-data [it alphabet]  
    (if (= it 1) (reduce str (shuffle alphabet)) 
     (str (reduce str (shuffle alphabet)) (make-control-data (dec it) alphabet))))  

少了一個遞歸步驟比以前的功能。雖然,前提條件和遞歸是不必要的,但我會感謝其他更好的方法遞歸地實現這個函數。