Clojure 查找依赖项的递归函数
我有一套地图。给定任何地图,我想找到它所依赖的所有地图。任何映射都将具有直接依赖关系。每个直接依赖项都将依次具有自己的依赖项,依此类推 我在编写递归函数时遇到问题。下面的代码给出了stackoverflow错误。(无论如何,该算法效率不高——我希望能帮助清理它) 下面是我的实现-Clojure 查找依赖项的递归函数,clojure,Clojure,我有一套地图。给定任何地图,我想找到它所依赖的所有地图。任何映射都将具有直接依赖关系。每个直接依赖项都将依次具有自己的依赖项,依此类推 我在编写递归函数时遇到问题。下面的代码给出了stackoverflow错误。(无论如何,该算法效率不高——我希望能帮助清理它) 下面是我的实现- find deps获取一个映射并返回一组映射:映射的直接依赖项 (查找deps[m])=>coll 以下功能- 检查作为基本条件的直接折旧是否为空 如果没有,它将映射所有直接DEP上的查找DEP。这就是步骤 这就是问题
find deps
获取一个映射并返回一组映射:映射的直接依赖项
(查找deps[m])=>coll
以下功能-
查找DEP
。这就是步骤
这就是问题的根源(defn find-all-deps
([m]
(find-all-deps m []))
([m all-deps]
(let [direct-deps (find-deps m)]
(if-not (seq direct-deps)
all-deps
(map #(find-all-deps % (concat all-deps %)) direct-deps)))))
在使用有向图时,确保不会两次访问图中的节点通常很有用。这个问题看起来很像许多图遍历问题,并且您的解决方案非常接近于正常的深度优先遍历,您只需要不遵循循环(或者不允许在输入中使用循环)。一种方法是在再次访问之前确保依赖项不在图中。不幸的是,map不适合这种情况,因为您映射的列表中的每个元素都不能知道同一列表中其他元素的依赖关系
reduce
更适合这里,因为您正在寻找一个答案
...
(if-not (seq direct-deps)
all-deps
(reduce (fn [result this-dep]
(if-not (contains? result this-dep)
(find-all-deps this-dep (conj result this-dep))
result)
direct-deps
#{}) ;; use a set to prevent duplicates.
是否可能存在依赖循环?请给出一个失败输入的示例。您的示例代码不完整,find deps函数未定义。您似乎在使用有序元组(向量数据类型)存储已找到的依赖项。这就产生了一个dep可以在其中多次出现的可能性。您可能应该切换到集
#{}
,该集会进行重复数据消除,因此当您接受依赖项时,不会多次获取其依赖项。