Clojure:如何计算列表中的事件?

时间:2014-09-02 01:09:23

标签: clojure

我对clojure还很新,所以如果这有点琐碎,我会道歉。基本上,问题出在"然后" if语句的一部分:( if(symbol?(first slist))。

;counts the number of occurences of 
(defn count-occurrences [s slist]
 (if (empty? slist)
   0
   (if (symbol? (first slist))
     (if (= (first slist) s)
       (+ 1 (count-occurrences s (rest slist)))
       (+ 0 (count-occurrences s (rest slist))))
     (count-occurrences s (first slist)))))                  ;Problem on this line

(println (count-occurrences 'x '((f x) y (((x z) x)))))

2 个答案:

答案 0 :(得分:2)

要计算嵌套列表中的元素,可以尝试以下函数:

(defn count-occurrences [s slist]
  (->> slist
       flatten
       (filter #{s})
       count))

测试:

user> (count-occurrences 'x '((f x) y (((x z) x))))
;; => 3
user> (count-occurrences 'y '((f x) y (((x z) x))))
;; => 1
user> (count-occurrences 'z '((f x) y (((x z) x))))
;; => 1

答案 1 :(得分:0)

正如Diego Basch评论的那样,算法的骨架应该是

(defn count-occurrences [s slist]
  (+ (count-occurrencies s (first slist))
     (count-occurrencies s (rest slist))))

......有一两个小问题:

  • 永远不会终止。
  • 它没有处理符号。
  • 它没有处理空列表。
  • slist可能不是列表,最终通过first来电, 不会。

我们如何处理这些问题?

  • 首先,测试是否处理符号。
  • 如果我们不是,请假设它是一个列表并测试它是否为空。
  • 如果没有,请应用骨架递归。

......给我们这样的东西:

(defn count-occurrences [s x]
  (if (symbol? x)
    (if (= x s) 1 0)
    (if (empty? x)
      0
      (+ (count-occurrences s (first x))
         (count-occurrences s (rest x))))))

......有效:

(count-occurrences 'x '((f x) y (((x z) x))))
;3

这个解决方案有几个问题(你会感到欣慰),这些问题在实践中使Mark's answer更优越。但是,如果你试图掌握递归,这将很好地做到。