我想更改以下Quicksort实现的契约,以返回执行排序操作所需的递归调用次数。
来源:http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Clojure
(defn qsort [[pivot & xs]]
(when pivot
(let [smaller #(< % pivot)]
(lazy-cat (qsort (filter smaller xs))
[pivot]
(qsort (remove smaller xs))))))
我想要做的是实现内部使用上述qsort实现的counted-qsort
。
我正在寻找一个如何做到这一点的例子。我怀疑可能涉及(bind ...)
。
答案 0 :(得分:5)
我在这个问题上玩了一会儿,这就是我想出的:
(defn counted-qsort [coll]
(let [count (atom 0) qs qsort]
(with-redefs [qsort (fn [coll]
(swap! count inc)
(prn coll)
(qs coll))]
(dorun (qsort coll)))
(deref count)))
此函数暂时重新定义qsort
,以便它可以管理一个原子,该原子包含最终调用qsort
次数的计数。 let绑定中的qs
允许在重新定义的版本中引用原始qsort
函数,以避免无限递归。
我使用“count”而不是“depth”,因为我不确定“depth”是否正确使用。此函数计算调用qsort
的次数,而不是“树”的实际深度。
我不知道用这种方法是否可以保持懒惰。
使用prn
进行调试的示例输出:
[1 2 3]
()
(2 3)
()
(3)
()
()
7 ;return value
我假设Clojure 1.3并且qsort
已在同一名称空间中定义。