我有一个x,y点列表存储为矢量矢量,我想找出界限。
例如,鉴于此:
[[0 0] [20 30] [-50 -70] [200 300]]
结果将是:
{:x -50, :y -70, :x2 200, :y2 300}
这是我到目前为止所拥有的。它给出了理想的结果,但看起来很冗长,而且对我来说并不是很好。
(defn get-stroke-bounds [vector-of-points]
(reduce (fn [m [x y]]
{:x (min (:x m Integer/MAX_VALUE) x)
:y (min (:y m Integer/MAX_VALUE) y)
:x2 (max (:x2 m Integer/MIN_VALUE) x)
:y2 (max (:y2 m Integer/MIN_VALUE) y)})
{}
(vector-of-points)))
有关如何改进它的任何想法?谢谢!
答案 0 :(得分:4)
你的解决方案已经很不错了!它是相当惯用的,并且在算法上最优的点数上也是O(n)(实际上比进行排序的方法更好)。
但是这里有另一种方法,你可能会发现它很有趣....主要是因为我是高阶函数的忠实粉丝: - )
(defn get-stroke-bounds [stroke]
(zipmap
[:x :y :x2 :y2]
(map
(fn [[getter reducer]]
(reduce
reducer
(map getter stroke)))
[
[first min]
[second min]
[first max]
[second max]])))
答案 1 :(得分:3)
如果我已经使用向量作为输入点,我希望返回值采用相同的格式。考虑到这一点,我认为这是一个很好的惯用解决方案:
(defn bounds
[points]
(let [xs (sort (map first points))
ys (sort (map second points))]
(list [(first xs) (first ys)]
[(last xs) (last ys)])))
答案 2 :(得分:1)
我不认为你的解决方案也不会出现问题。但是如果你喜欢更少的代码,你可以尝试一个有序的集合。
(let [v [[0 0] [20 30] [-50 -70] [200 300]]
v-sorted (apply sorted-set v)]
[(first v-sorted) (last v-sorted)])
更新:很抱歉上面的代码不正确。有必要对separetely x和y进行排序以找到一个不是最大或最小点的边界。除非设置首选,否则约翰的solution会更好。