Common elements in two lists with duplicates

假装没事ソ 提交于 2019-12-06 14:55:29

Here's my implementation. It uses maps and sets to hold intermediate data, and thus is not lazy like your version, but I think it is more readable and will have better overall performance characteristics (your version has quadratic time complexity to realize the results from common-elements).

(require '[clojure.set :as set])
(defn common-elements [& colls]
  (let [freqs (map frequencies colls)]
    (mapcat (fn [e] (repeat (apply min (map #(% e) freqs)) e))
            (apply set/intersection (map (comp set keys) freqs)))))
A. Webb

Not the most efficient, but fairly concise:

(defn common [& ss] 
  (let [fs (map frequencies ss), ks (map set ss)]
    (select-keys (apply merge-with min fs) 
                 (reduce clojure.set/intersection ks))))

Returns maps of values and counts

(common [1] [1]) ;=> {1 1}
(common [1 2] [1 1]) ;=> {1 1}
(common [1 1] [1 1 1]) ;=> {1 2}

Another approach, modified from my own question Idiomatic/Efficient Clojure way to intersect two a priori sorted vectors?,

(defn common [x y] 
  (loop [x (sort x) y (sort y) acc []] 
    (if (and x y)
      (let [x1 (first x) 
            y1 (first y)] 
      (cond 
        ( < x1 y1) (recur (next x) y acc) 
        ( > x1 y1) (recur x (next y) acc) 
        :else (recur (next x) (next y) (conj acc x1))))
    acc)))

which returns a vector as in the original question

(common [1 1 1 2 2 3] [1 1 2 5]) ;=> [1 1 2]

Of course if you know your inputs are sorted, you may omit the sort, and if you furthermore know they are vectors you can use the optimizations provided by amalloy in answer to the referenced question.

(defn get-commons [l1 l2]
  (let [f1 (frequencies l1) 
        f2 (frequencies l2)
        common (clojure.set/intersection (set l1) (set l2))
        love (merge-with (fn [val1 val2] (min val1 val2)) f1 f2)] 
    (mapcat #(repeat (love %) %) common)))

The function is similar to the ones given in previous answers. I still submit this answer for Clojure beginners who may stumble on this question. I believe the function makes clearer the steps needed for the function to evaluate to a result.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!