查找已排序的浮动集之间的最小差异

时间:2016-09-21 22:16:24

标签: clojure sortedset

如果我有一个排序的浮点数组,我如何找到该排序集中任何2个值之间的最小差异?

例如,如果有序集包含

#{1.0 1.1 1.3 1.45 1.7 1.71}

然后我之后的结果将是0.01,因为1.71和1.7之间的差异是该有序集合中任何2个值之间的最小差异。

2 个答案:

答案 0 :(得分:2)

修改

正如艾伦向我指出的那样,问题是这是一个排序集,所以我们可以做得更简单:

(def s (sorted-set 1.0 1.1 1.3 1.45 1.7 1.71))
(reduce min (map - (rest s) s)))
=> 0.01

原始答案

假设该集合是无序的,尽管排序可能会更好。

给出

(def s #{1.0 1.1 1.3 1.45 1.7 1.71})

我们可以为列表中的每个数字获取相关对,如下所示,将其与右侧的所有数字配对:

(def pairs 
   (loop [r [] s (into [] s)]
      (if-let [[f & v] s]
         (recur (concat r (for [i v] [f i]))
                v)
         r)))
=> ([1.0 1.45] [1.0 1.7] [1.0 1.3] [1.0 1.1] [1.0 1.71] [1.45 1.7] [1.45 1.3] 
    [1.45 1.1] [1.45 1.71] [1.7 1.3] [1.7 1.1] [1.7 1.71] [1.3 1.1] [1.3 1.71] 
    [1.1 1.71])

现在,我们要查看每对之间差异的绝对值:

(defn abs [x] (Math/abs x))

将它们放在一起,并获得最小值:

(reduce min (map (comp abs (partial apply -)) pairs))

这将为我们提供所需的输出0.01

最后一行可以更明确地写为

(reduce min
    (map (fn[[a b]]
           (abs (- a b)))
         pairs))

答案 1 :(得分:-2)

我认为使用Clojure内置函数partition是最简单的方法:

(ns clj.core
  (:require [tupelo.core :as t] ))
(t/refer-tupelo)

(def vals [1.0 1.1 1.3 1.45 1.7 1.71])
(spyx vals)

(def pairs (partition 2 1 vals))
(spyx pairs)

(def deltas (mapv #(apply - (reverse %)) pairs))
(spyx deltas)

(println "result=" (apply 

vals => [1.0 1.1 1.3 1.45 1.7 1.71]
pairs => ((1.0 1.1) (1.1 1.3) (1.3 1.45) (1.45 1.7) (1.7 1.71))
deltas => [0.10000000000000009 0.19999999999999996 0.1499999999999999 0.25 0.010000000000000009]
result= 0.010000000000000009