Clojure中的递归函数失败断言

时间:2011-11-07 03:45:33

标签: string random recursion clojure

以下是递归函数:

(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)的字符串。

有人能看出什么问题吗?

2 个答案:

答案 0 :(得分:2)

你的函数显然愿意接受it = 0,所以你的前提条件不应该禁止输入。零是你的递归基本情况,而不是错误。如果我在这个函数上加上一个先决条件(虽然我不愿意),那就是[(not (neg? it))]

如果我是从头开始写这个,我不会费心去除所有的递归噪音,只是简单地说:

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

答案 1 :(得分: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))))    

比前一个函数少一个递归步骤。虽然前置条件和递归是不必要的,但我会欣赏其他更好的方法来递归地实现这个函数。