我试图在https://iloveponies.github.io/120-hour-epic-sax-marathon/recursion.html做练习20。这是我的代码:
(defn my-frequencies-helper [freqs a-seq]
(let [first-elem (first a-seq)
rest-of-seq (rest a-seq)]
(if (nil? first-elem)
freqs
(if (contains? freqs first-elem)
(assoc freqs first-elem (inc (get freqs first-elem)))
(assoc freqs first-elem 1)))))
(defn my-frequencies [a-seq]
(my-frequencies-helper {} a-seq))
问题是这不是递归的。不知何故,我需要在更新my-frequencies-helper
地图后将以下行添加到freqs
:
(my-frequencies-helper freqs rest-of-seq)
由于它不依赖于if
函数的分支,因此我无法在不向if
函数添加太多参数的情况下查看如何执行此操作。即它不适合cond
或if
,因为它是我在执行另一个功能上无关的步骤后要调用的一个步骤。
我可能错了,但是我只是想在更新地图之后递归调用my-frequencies-helper
,例如在python中:
freqs[first-elem] = freqs[first-elem] + 1
my-frequencies-helper(freqs, rest-of-seq) # just another step to execute
我如何将其与我的代码联系起来(或者更可能的是,这将是另一种简单的方法)?
答案 0 :(得分:4)
我们可以在解构的帮助下简化这段代码:
(defn my-frequencies-helper
[freqs [first-elem & rest-of-seq :as a-seq]]
(if (empty? a-seq)
freqs
(let [updated-freqs (if (contains? freqs first-elem)
(assoc freqs first-elem (inc (get freqs first-elem)))
(assoc freqs first-elem 1))]
(my-frequencies-helper updated-freqs rest-of-seq))))
此外还有一个常见的习惯用语
(if (contains? freqs first-elem)
(assoc freqs first-elem (inc (get freqs first-elem)))
(assoc freqs first-elem 1))
以下是等效的,只要您不将nil存储在其中一个数字的位置:
(update-in freqs [first-elem] (fnil inc 0))
这给我们留下了以下简化函数:
(defn my-frequencies-helper
[freqs [first-elem & rest-of-seq :as a-seq]]
(if (empty? a-seq)
freqs
(my-frequencies-helper (update-in freqs [first-elem] (fnil inc 0)) rest-of-seq)))
答案 1 :(得分:0)
对于列表中的每个项目,您都希望在结果词典中查找,看看该项目是否已经存在,如果是,您将保存+1,如果不是,只需在该字典中存储1。
有了这个,您可以通过简单的递归来解决它,或者使用reduce。
扰流:
(defn my-frequencies [x] (reduce(fn[t n](assoc t n (inc(get t n 0)))) {} x))