父/子isa中的最低共同祖先?Clojure中的层次结构
假设我们有这样的父/子层次结构:父/子isa中的最低共同祖先?Clojure中的层次结构,clojure,lowest-common-ancestor,Clojure,Lowest Common Ancestor,假设我们有这样的父/子层次结构: (derive ::integer ::decimal) (derive ::positive-integer ::integer) (derive ::long ::integer) 什么是Clojure惯用语来实现在这样的层次结构中找到最低共同祖先的方法?即: (lca ::positive-integer ::long) ; => ::integer 我最初的想法包括使用递归函数遍历每个参数的父类的组合,但我怀疑可能有更好的方法 我的动机是将其用
(derive ::integer ::decimal)
(derive ::positive-integer ::integer)
(derive ::long ::integer)
什么是Clojure惯用语来实现在这样的层次结构中找到最低共同祖先的方法?即:
(lca ::positive-integer ::long) ; => ::integer
我最初的想法包括使用递归函数遍历每个参数的父类的组合,但我怀疑可能有更好的方法
我的动机是将其用作多方法的分派函数,该多方法接受2个参数,并根据参数的类型分派到最适合的实现。函数返回一个集合,因此您需要(需要[clojure.set:as s])
现在写:
(defn lca [h1 h2]
(let [a1 (into #{} (conj (ancestors h1) h1))
a2 (into #{} (conj (ancestors h2) h2))
ac (s/intersection a1 a2)]
(apply (partial max-key (comp count ancestors)) ac)))
让我们试试看
stack-prj.hierarchy> (derive ::integer ::decimal)
nil
stack-prj.hierarchy> (derive ::positive-integer ::integer)
nil
stack-prj.hierarchy> (derive ::long ::integer)
nil
stack-prj.hierarchy> (lca ::positive-integer ::long)
:stack-prj.hierarchy/integer
其工作原理如下:我使用祖先
获取每种类型的祖先集。对于这两种类型,我使用conj
,将类型本身添加到结果集中(因为我认为(lca::integer::long)
应该返回integer
而不是decimal
)。使用set intersection,我将所有公共祖先存储到变量ac
中
在普通祖先中,我想知道哪一个祖先最多(comp count祖先)
是一个函数,它采用一种类型并返回其拥有的祖先数。我将max key
部分应用于此函数,然后(使用apply
)将结果函数应用于集合ac
。结果是祖先数量最多的共同祖先,或者说是最少的共同祖先
(请注意,lca
如果您传递两种类型而没有任何共同祖先,则会给出一个错误!您应该自己决定如何处理此情况。)谢谢!虽然祖先
可能应该包装在集合
中,以防止交集
在提供由conj
创建的列表时抛出错误,但在没有祖先的情况下,将其设置为零。顺便问一句,为什么要将使用到#{}
而不是集合
,感谢您向我介绍max key
!我已经使用Clojure好几年了,但我还没有遇到过这个函数。我习惯于使用转换为作为将一种收藏类型转换为另一种收藏类型的go-to函数<代码>设置
在这种情况下同样有效;这不是我的风格。