2011-11-07 63 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))))  

少了一个递归步骤比以前的功能。虽然,前提条件和递归是不必要的,但我会感谢其他更好的方法递归地实现这个函数。