找到一组排序的浮点数之间的最小差异
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
如果我有一组已排序的浮点数,我如何找到该已排序集合中任意 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