【问题标题】:Clojure sorted-map: find largest key that is less than or equal to x (floor key)Clojure sorted-map:找到小于或等于 x 的最大键(楼层键)
【发布时间】:2017-03-14 22:44:47
【问题描述】:

我有一个问题,我有一些代表时间的键和一些值。一个小例子:

 (sorted-map -4 "a" -1 "b" 2 "c" 3 "d")

对于给定的 x,我想找到小于或等于 x 的最大键。

例如,在 Julia DataStructures 包中有一个排序字典,其方法如下:

searchsortedlast(sc,k) 参数 sc 是 SortedDict、SortedMultiDict 或 SortedSet 和 k 是一个键。此例程返回 容器中键小于或等于 k ​​的最后一项。如果 没有这样的密钥,则返回启动前的半令牌。 时间:O(c log n)

我一直在尝试在 clojure 中查找有关类似功能的文档,但没有找到任何东西。 我的幼稚做法如下:

(apply max (filter #(

但我认为这是次优的,因为它首先收集所有键,然后过滤它们,从而产生不必要的计算。

我的问题是 1)是如果已经有一个我找不到的实现这个的函数。 2)如果不是这种情况,我是否应该搜索 Java 数据结构并使用 java 数据结构和相关方法 3) 是否可以让我的方法变得懒惰以提高效率?

编辑:

来自 Java 的 TreeMap:

K floorKey(K key) 返回小于等于 给定键,如果没有这样的键,则返回 null。

这就是我使用 clojure sorted-map 寻找的东西。我应该放弃 sorted-map 并使用 Java 树状图吗?

EDIT2:

我发现了这个 https://github.com/clojure/data.avl 它提供了一种具有“最近键”功能的替代排序映射实现

【问题讨论】:

    标签: java data-structures clojure functional-programming


    【解决方案1】:

    对于排序集合,如排序地图,您可以使用 subseqrsubseq

    在您的示例中,要查找最大键等于或小于 x 的条目,您可以使用:

    (let [m (sorted-map -4 "a" -1 "b" 2 "c" 3 "d")
          x 0]
      (first (rsubseq m <= x)))
    ;; => [-1 "b"]
    

    【讨论】:

    • 你知道这个查找的计算复杂度吗?对于树形图,它将是 log n
    • sorted-seq 中元素的访问是log n (clojure.org/reference/data_structures#Maps)。实际上他们是PersistentTreeMapunderhood (github.com/clojure/clojure/blob/clojure-1.8.0/src/clj/clojure/…)。 subseqrsubseq 分别作为 &gt;/&gt;=&lt;/&lt;= 的原始集合上的“视图”实现,或者根据 take-while 实现其他测试功能。
    • 我找到了一个新的 sorted-map 实现(参见 EDIT 2)。使用您建议的方式而不是使用链接实现有什么好处吗?
    • 关于 clojure/data.avl 这一切都取决于您的要求。它的文档提供了有关clojure.core 排序集和映射之间差异的详细信息(例如,它们提供临时版本,它们具有更快的查找速度但更慢assoc|update 并增加了一些内存开销)。所以归结为您的要求。
    猜你喜欢
    • 2016-09-30
    • 1970-01-01
    • 2021-06-09
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多