【问题标题】:Recursive Function in Clojure Fails AssertionClojure 中的递归函数断言失败
【发布时间】:2011-11-07 03:45:33
【问题描述】:

以下是递归函数:

(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 (count ["a" "b"])) = 4 的随机字符串。

它打破了前置条件(pos? it),返回一个长度为(it+1)*length(alphabet)的字符串。

谁能看出有什么问题?

【问题讨论】:

  • 建议使用高阶函数而不是显式递归,如@amalloy 的答案所示

标签: string random recursion clojure


【解决方案1】:

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

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

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

【讨论】:

【解决方案2】:

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

 (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))))    

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多