String Clojure中的递归函数在断言中失败

String Clojure中的递归函数在断言中失败,string,random,recursion,clojure,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-c

以下是一个递归函数:

(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”]
则函数应使用字母表中的所有字母
[“a”“b”]
生成长度为
(*2(计数[“a”“b”]))=4的随机字符串

它将打破前置条件
(pos?It)
,并返回一个长度为
(It+1)*长度(字母表)
的字符串


有人知道怎么了吗

您的函数显然愿意接受
it
=0,因此您的前提条件不应禁止该输入。零是递归的基本情况,而不是错误。如果我在这个函数上加一个前提条件(尽管我不会),它将是
[(not(neg?it))]

如果我是从头开始写这篇文章,我不会为所有的递归噪音而烦恼,只不过:

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

这是一个使用递归的正确函数:

 (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))))  
(使控制数据2[“a”“b”“c]”)返回
“bcacab”

(计数(使控制数据为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))))    

与上一个函数相比,递归步骤少了一步。虽然前置条件和递归是不必要的,但我希望有其他更好的方法递归地实现这个函数

我明白了,当它=0时,(pos?it)返回false。谢谢。@sesanker是的,零不是正的。但这不是负面的。建议在显式递归上使用高阶函数,如@amalloy的答案所示