【发布时间】:2014-10-20 22:41:59
【问题描述】:
我知道有多种方法可以使用 Clojure 解决排列问题。 我尝试使用 Core.Logic 创建 DCG(定句语法),但是 库的 DCG 部分太实验性了,没有用。
在下面的代码中,我尝试了两种不同的方法。一个是列表推导(注释掉),类似于我在 Haskell 中解决这个问题的方式。
第二种方法使用 MapCat 将 cons/first 应用于每个返回值 递归调用排列。删除项目确保我不会在每个位置多次使用相同的字母。
谁能解释一下列表理解方法有什么问题以及 MapCat 方法有什么问题。在 Haskell 中推理这类问题要容易得多 - 我是否缺少关于 Clojure 的一些观点?
(defn remove-item [xs]
(remove #{(first xs)} xs )
)
(defn permutation [xs]
(if (= (count xs) 1)
xs
;(for [x xs y (permutation (remove-item xs))
; :let [z (map concat y)]]
; z)
(mapcat #(map cons first (permutation (remove-item %)) ) xs)
)
)
编辑:@thumbnail 已经解决了 cmets 中的 MapCat 子问题
【问题讨论】:
-
DCG 是 TLA 对吧? recPermute 是做什么的?
-
@amalloy - 我的问题不是关于如何解决 Clojure 中的排列。除了 stackoverflow 响应之外,网上还有大量的示例排列代码。我的问题是为什么我尝试的实现不起作用 - 我缺少什么更深层次的概念。很多人在这里提出半生不熟的问题 - 这是了解 clojure 工作原理的真正尝试和真正的问题。
-
@stevemacn 您可以随时使用更具体的标题再次提问,例如“我的 Clojure 排列实现有什么问题?”
-
@stevemacn
(partial cons x)等价于#(cons x %)或(fn [coll] (cons x coll))。它将consesx放到它的顺序参数上,map贯穿perms 中的所有其他s。封闭的mapcat连接将此过程应用于s的每个元素的结果,被视为一个序列。因此,该函数接受一个 set 参数,但返回一个 sequences 序列。你应该知道 - 基本上是你写的 :)。 -
@stevemacn 所以你对
(partial cons x)所做的事情是正确的;和(disj s x)返回 设置s没有元素x。顺便说一句,我从您的代码中得到的印象是 Haskell 可以将非空集合解构为任意成员x和剩余的 setxs。在 Clojure 中试试这个,xs将是一个序列,而不是一个集合。您可以在ClojureDocs 或Grimoire 查找标准函数,例如partial或conj。最后,如果您想继续这样做,请遵循 @amalloy 的隐含建议并在其他地方重新打开修改后的问题。
标签: clojure functional-programming clojure-core.logic