我有这个经典算法练习:在这个数组中有多少三倍总和为零?在Java中实现它没问题:
int count = 0;
for (int i = 0; i < array.length - 2; i++) {
(for int j= i+1; j < array.length -1; j++) {
(for int k = j + 1; k < array.length; k++) {
if (array[i] + array[j] + array[k] == 0) {
count++;
}
}
}
}
return count;
虽然我怎么会在Clojure中这样做?我问自己:我怎么能在Clojure中做嵌套循环。
但是this question and answer并没有真正解决我的问题,因为它需要两个相同的数组并组合所有元素(也是相同的元素,例如1和1)。
相关问题:如何从集合中获取三元组的所有组合?
注意:我们明确要求不对数组进行排序。我知道有更快的算法。
编辑:添加“== 0”条件。
答案 0 :(得分:6)
你也可以用列表理解来完成它,而根本没有操作索引:
user> (def data [1 -2 1 1 -3 2])
#'user/data
user> (defn tails [data]
(take-while seq (iterate rest data)))
#'user/tails
user> (for [[x & xs] (tails data)
[y & ys] (tails xs)
[z] (tails ys)
:when (zero? (+ x y z))]
[x y z])
;;=> ([1 -2 1] [1 -2 1] [1 -3 2] [-2 1 1] [1 -3 2] [1 -3 2])
答案 1 :(得分:3)
你可以在clojure中使用visible-*
循环,类似于java。
<强> 1。仅计算总和为0的组合计数,
for
REPL示例,
(defn three-sum-count [array]
(let [three_sum
(for [i (range 0 (- (count array) 2))
j (range (+ 1 i) (- (count array) 1))
k (range (+ 1 j) (count array))]
(if (zero? (+ (get array i) (get array j) (get array k))) 1 0))]
(reduce + three_sum)))
<强> 2。列出总和为零的所有组合,
user=> (three-sum-count [1, -2])
0
user=> (three-sum-count [1, -2, 1])
1
user=> (three-sum-count [1, -2, 1, 1])
3
user=> (three-sum-count [1 -2 1 1 -3 2])
6
REPL示例
(defn three-sum-combinations [array]
(remove empty?
(for [i (range 0 (- (count array) 2))
j (range (+ 1 i) (- (count array) 1))
k (range (+ 1 j) (count array))]
(if (zero? (+ (get array i) (get array j) (get array k)))
[(get array i) (get array j) (get array k)]
[]))))
你也可以用这种方式计算出多少种组合,
user=> (three-sum-combinations [1, -2])
()
user=> (three-sum-combinations [1, -2, 1])
([1 -2 1])
user=> (three-sum-combinations [1, -2, 1, 1])
([1 -2 1] [1 -2 1] [-2 1 1])
user=> (three-sum-combinations [1 -2 1 1 -3 2])
([1 -2 1] [1 -2 1] [1 -3 2] [-2 1 1] [1 -3 2] [1 -3 2])