找到一组排序的浮点数之间的最小差异

Finding the smallest difference between a sorted-set of floats

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

例如,如果排序集包含

#{1.0 1.1 1.3 1.45 1.7 1.71}

那么我得到的结果就是 0.01,因为 1.71 和 1.7 之间的差异是该排序集中任意 2 个值之间的最小差异。

编辑

正如 Alan 向我指出的那样,问题表明这是一个有序集,因此我们可以更简单地做到这一点:

(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))

我认为使用 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