Vector Clojure,比较整数向量:为什么;更长的;向量始终是“;“大”字;?有补救办法吗?
它的工作原理如下:Vector Clojure,比较整数向量:为什么;更长的;向量始终是“;“大”字;?有补救办法吗?,vector,clojure,comparator,Vector,Clojure,Comparator,它的工作原理如下: pcc.core=> (compare [4] [2 2]) -1 pcc.core=> (compare [4 0] [2 2]) 1 我想要一个具有“字符串语义”的向量比较器: 有没有一个简单、好的方法来得到我想要的东西?也许是这样 (defn compare-like-strings [a b] (let [res (first (drop-while zero? (map compare a b)))] (if (nil? res)
pcc.core=> (compare [4] [2 2])
-1
pcc.core=> (compare [4 0] [2 2])
1
我想要一个具有“字符串语义”的向量比较器:
有没有一个简单、好的方法来得到我想要的东西?也许是这样
(defn compare-like-strings [a b]
(let [res (first (drop-while zero? (map compare a b)))]
(if (nil? res)
0
res)))
其思想是进行两两比较,返回-1、0或1的seq,然后删除所有前导的0。第一个非零元素是第一个不同的元素。可能是这样的
(defn compare-like-strings [a b]
(let [res (first (drop-while zero? (map compare a b)))]
(if (nil? res)
0
res)))
其思想是进行两两比较,返回-1、0或1的seq,然后删除所有前导的0。第一个非零元素是第一个不同的元素。如果两个向量长度相同,则比较似乎有效,因此让我提供以下内容:
(defn compare-vectors
[a b]
(compare
(reduce conj a (map #{} b))
(reduce conj b (map #{} a))))
这基本上是在运行比较之前,根据需要使用尽可能多的nil
s填充输入。我喜欢它的外观(它应该完全符合您的要求),但我不确定是否会向任何人推荐它
编辑:我可能不会-效率非常低。如果两个向量的长度相同,则比较似乎有效,因此让我提供以下内容:
(defn compare-vectors
[a b]
(compare
(reduce conj a (map #{} b))
(reduce conj b (map #{} a))))
这基本上是在运行比较之前,根据需要使用尽可能多的nil
s填充输入。我喜欢它的外观(它应该完全符合您的要求),但我不确定是否会向任何人推荐它
编辑:我可能不会-效率太低了。怎么样:
(defn compare-like-strings [[x & xs] [y & ys]]
(let [c (compare x y)]
(if (and (zero? c) (or xs ys))
(recur xs ys)
c)))
那么:
(defn compare-like-strings [[x & xs] [y & ys]]
(let [c (compare x y)]
(if (and (zero? c) (or xs ys))
(recur xs ys)
c)))
为什么不使用
subvec
(defn compare-like-strings
[vec1 vec2]
(let [len (min (count vec1) (count vec2))]
(compare (subvec vec1 0 len)
(subvec vec2 0 len))))
为什么不使用
subvec
(defn compare-like-strings
[vec1 vec2]
(let [len (min (count vec1) (count vec2))]
(compare (subvec vec1 0 len)
(subvec vec2 0 len))))
到目前为止是
(defn cmpv-int
"Compare vectors of integers using 'string semantics'"
[vx vy]
(let [res (first (drop-while zero? (map compare vx vy)))
diffenence (- (count vx) (count vy))]
(if res res diffenence)
)
)
基于费边方法。到目前为止
(defn cmpv-int
"Compare vectors of integers using 'string semantics'"
[vx vy]
(let [res (first (drop-while zero? (map compare vx vy)))
diffenence (- (count vx) (count vy))]
(if res res diffenence)
)
)
基于Fabian方法。正如我在对Diego答案的评论中所说,我认为最没有创意的方法在这里是最好的:只需编写一个循环,列举所有案例,然后努力完成它。作为奖励,这种方法也适用于任意序列,可能是惰性的,因为我们不需要依赖任何特定于向量的技巧
(defn lexicographic-compare
([xs ys]
(lexicographic-compare compare xs ys))
([compare xs ys]
(loop [xs (seq xs) ys (seq ys)]
(if xs
(if ys
(let [c (compare (first xs) (first ys))]
(if (not (zero? c))
c
(recur (next xs), (next ys))))
1)
(if ys
-1
0)))))
正如我在对迭戈答案的评论中所说的,我认为最没有创意的方法在这里是最好的:只需编写一个循环,列举所有案例,然后努力完成它。作为奖励,这种方法也适用于任意序列,可能是惰性的,因为我们不需要依赖任何特定于向量的技巧
(defn lexicographic-compare
([xs ys]
(lexicographic-compare compare xs ys))
([compare xs ys]
(loop [xs (seq xs) ys (seq ys)]
(if xs
(if ys
(let [c (compare (first xs) (first ys))]
(if (not (zero? c))
c
(recur (next xs), (next ys))))
1)
(if ys
-1
0)))))
不要忘记所有元素都相同的情况-它应该产生0。此外,如果我们比较
[1 2]
和[1 1 1]
,会怎么样?对,刚刚注意到并修复了两者相等的情况。我想[1 1 2]
与[1 1]
的情况取决于您的需求?我想是Alexey的电话。虽然代码很好,但长度上的改进是受欢迎的:)。[1]应该小于[1 2]不要忘记所有元素都相同的情况-它应该产生0。此外,如果我们比较[1 2]
和[1 1]
,会怎么样?对,只是注意到了这一点,并修复了两者相等的情况。我想[1 1 2]
与[1 1]
的情况取决于您的需求?我想是Alexey的电话。虽然代码很好,但长度上的改进是受欢迎的:)[11]应该小于[12]为什么这是“字符串语义”?我希望字符串比较具有与vector相同的行为(这至少是Clojure和Java的行为)。@AlexMiller,(比较“abc”“ac”)
=>-1,但(比较[1 2 3][1 3])
=>1。@AlexMiller字符串传统上是按字典进行比较的,Clojure和Java都继承了这一传统。不同的是,向量在内容之前比较长度,而字符串只有在前N项比较相同时才使用长度。啊,我明白你的意思。为什么这是“字符串语义”?我希望字符串比较具有与vector相同的行为(这至少是Clojure和Java的行为)。@AlexMiller,(比较“abc”“ac”)
=>-1,但(比较[1 2 3][1 3])
=>1。@AlexMiller字符串传统上是按字典进行比较的,Clojure和Java都继承了这一传统。不同之处在于向量在内容之前比较长度,而字符串仅在前N项比较相同时才使用长度。啊,我明白你的意思。这忽略了一些边缘情况,通过xs
和ys
上的nil双关以及检查空输入的失败。例如,(与字符串[nil][])
返回0。@amalloy捕捉良好。最好将它们与普通的旧循环进行比较。如果您用完了一个,并且到目前为止它一直在匹配,则返回-1或1,具体取决于哪个用完了。我的经验法则基本上是永远不要使用[x&xs]
解构。理论上这很吸引人,但实际上我总是想变得更懒,或者不能确定至少有一个元素,或者类似的东西,所以我最终使用了seq
,first
,和next
或rest
。我最后用count
和subvec
修复了它,但代码太难看了,无法发布。关于[x&xs]
的优点是,在这种情况下,它是复合的,因为有两个序列。我同意在循环中进行比较是最好的:当你处理两个不同长度的序列时,最不具创造性和最乏味的解决方案胜过所有聪明的HOF方法。如果你小心的话,你可以使它适用于任意的序列和向量。这会错过一些边缘情况,通过xs
和ys
上的nil双关以及检查空输入的失败。例如,(与字符串[nil][])
返回0。@amalloy捕捉良好。最好将它们与普通的旧循环进行比较。如果您用完了一个,并且到目前为止它一直在匹配,则返回-1或1,具体取决于哪个用完了。我的经验法则基本上是永远不要使用[x&xs]
解构。这在理论上很吸引人,但在实践中我总是想变得更懒,或者不能确定至少有一个因素,或者