3Sum在Clojure中使用for

时间:2017-09-22 06:10:00

标签: clojure

我有这个经典算法练习:在这个数组中有多少三倍总和为零?在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”条件。

2 个答案:

答案 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])