Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Clojure序列中修剪周期的不引人注目的方法_Clojure - Fatal编程技术网

在Clojure序列中修剪周期的不引人注目的方法

在Clojure序列中修剪周期的不引人注目的方法,clojure,Clojure,我正在尝试编写一个惰性seq来生成给定输入int的 我喜欢这个函数,因为它非常清晰地映射到数学定义: (defn collatz “返回从n开始到1结束的Collatz序列的延迟序列(如果 永远。” [n] (下期[x] (如果(偶数?x) (/x2) (inc(*3 x))] (迭代下一项n))) 问题在于,由于Collatz序列的行为方式,这会产生无穷多个序列: (取10(5)) => (5 16 8 4 2 1 4 2 1 4) 我可以通过添加(take while#(not=1%)…

我正在尝试编写一个惰性seq来生成给定输入int的

我喜欢这个函数,因为它非常清晰地映射到数学定义:

(defn collatz
“返回从n开始到1结束的Collatz序列的延迟序列(如果
永远。”
[n]
(下期[x]
(如果(偶数?x)
(/x2)
(inc(*3 x))]
(迭代下一项n)))
问题在于,由于Collatz序列的行为方式,这会产生无穷多个序列:

(取10(5))
=> (5 16 8 4 2 1 4 2 1 4)
我可以通过添加
(take while#(not=1%)…)
轻松地放弃循环,但1是序列的一部分。我所想到的所有其他方法都是丑陋的,混淆了Collatz序列的数学核心

(我考虑过将看到的值存储在原子中,并在
take while
谓词中使用它,或者只是在原子中存储一个标志以达到类似的效果。但我觉得有更好、更漂亮、更少干扰的方法来做我想做的事情。)


所以我的问题是:什么是检测和修剪无限序列中循环的干净方法?或者,我可以用某种方式(可能使用
for
)生成我的lazy seq,当它达到
1
(包括)时自动修剪吗?

下面看起来或多或少像是定义的直译,并给出了您想要的结果:

(defn collatz-iter [x]
  (cond (= x 1) nil
        (even? x) (/ x 2)
        :else (inc (* 3 x))))

(defn collatz [n]
  (take-while some? (iterate collatz-iter n)))

(collatz 12) ;; => (12 6 3 10 5 16 8 4 2 1)

基本上,您可以使用
nil
作为停止序列的值,从而保持最后的1。

您还可以使用另一种方法,即递归惰性序列生成。这对于此类任务非常常见,不会破坏惰性序列抽象并避免中间序列的创建:

(defn collatz [n]
  (if (== n 1)
    (list 1)
    (lazy-seq (cons n (collatz (if (even? n)
                                 (/ n 2)
                                 (inc (* 3 n))))))))

user> (collatz 12)
;;=> (12 6 3 10 5 16 8 4 2 1)

我完全没有意识到,
collatz iter
/
next term
正在决定下一个术语的重要性——因此,如果它看到
1
,只需发出一个终止符占位符(
nil
)作为下一个术语。是的,非常直截了当。谢谢。对于来这里搜索“Clojure”和“Collatz”的任何人:这里的备忘录也是一个很好的解决方案,与
cons
lazy seq
相结合。您可以重用在Aleph的答案中创建的
collatz iter
函数。编写
更简单(cons n(when(not=n1)(lazy seq(collatz…))