2017-01-16 19 views
2

出现一次以上列表中的号码我有数字2 4 3 7 4 9 8 5 12 24 8如何找到使用的Clojure

我需要找到其重复一次以上编号的列表在clojure。

我用frequencies函数查找。但结果是

{2 1,4 2,3 1,7 1,9 1,8 2,5 1,12 1,24 1} 

我intially认为应该把它们看做key value,然后取每个键值一次,看看如果val> 1。如果值大于1,那么我需要INC 1.

但我无法解决这个问题。

任何人都可以请帮助我?

无论如何,我可以做到这一点[[2 1][4 2][3 1][7 1][9 1][8 2][5 1][12 1][24 1]]和考虑每个向量递归或任何更好的想法,你可以想到的。

谢谢。

回答

1

功能下面就继续你已经陷入其中:

(defn find-duplicates [numbers] 
    (->> numbers 
     (frequencies) 
     (filter (fn [[k v]] (> v 1))) 
     (keys))) 

它会过滤具有值大于1,然后提取其键映射条目。

(find-duplicates [2 4 3 7 4 9 8 5 12 24 8]) 
;; => (4 8) 
0

您正处在正确的轨道上。

如果你在散列图上搜索, G。通过地图,你得到你所描述的KV元组结构,并可以在元变换功能解构个别元组:如果你想重复项目

(->> s 
    (frequencies) 
    (map (fn [[number times]] 
      (cond-> number   ; take number 
       (> times 1) (inc))))) ; inc if (times > 1), otherwise return number 
1

(defn repeated [coll] 
    (->> coll 
     frequencies 
     (remove #(= 1 (val %))) 
     keys)) 

(repeated [2 4 3 7 4 9 8 5 12 24 8]) 
;(4 8) 

如果你只是想数其中:

(defn repeat-count [coll] 
    (->> coll 
     frequencies 
     (remove #(= 1 (val %))) 
     count)) 

(repeat-count [2 4 3 7 4 9 8 5 12 24 8]) 
;2 

你可以做到这一点懒洋洋,所以它将在循环顺序工作:

(defn repeated [coll] 
    ((fn ff [seen xs] 
    (lazy-seq 
     (when-let [[y & ys] (seq xs)] 
     (case (seen y) 
     ::several (ff seen ys) 
     ::once (cons y (ff (assoc seen y ::several) ys)) 
     (ff (assoc seen y ::once) ys))))) 
    {} coll)) 

(repeated [2 4 3 7 4 9 8 5 12 24 8]) 
;(4 8) 

这与核心distinct相似。


......最后,为了简便起见,...

(defn repeated [coll] 
    (for [[k v] (frequencies coll) :when (not= v 1)] k)) 

我偷了使用keysPiotrek Byzdyl's answer。它只适用于地图。但在一系列的map-entries中完美地工作。

0

您可以使用这种方法。

(def c [2 4 3 7 4 9 8 5 12 24 8]) 

(->> c 
    sort 
    (partition-by identity) 
    (filter #(> (count %) 1)) 
    (map first)) 
+0

这是很好的,但计算更贵,达到同样的计算复杂度等解决方案,您可以选择'组by'没有'sort'(这是'O(nlogn)') – fl00r