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
如何将while循环转换为clojure代码_Clojure - Fatal编程技术网

如何将while循环转换为clojure代码

如何将while循环转换为clojure代码,clojure,Clojure,例如,扩展欧几里德算法(引自wiki): 我试过并得到了: (defn extended-gcd [a b] (loop [a a b b x 0 y 1 lx 1 ly 0] (if (zero? b) [lx ly] (recur b (mod a b) (- lx (* (int (/ a b)) x)) (- ly (* (int (/ a b)) y)) x y)

例如,扩展欧几里德算法(引自wiki):

我试过并得到了:

 (defn extended-gcd 
  [a b]
  (loop [a a b b x 0 y 1 lx 1 ly 0]
     (if (zero? b)
      [lx ly]
      (recur b (mod a b)
             (- lx (* (int (/ a b)) x))
             (- ly (* (int (/ a b)) y))
             x y))))

我想我可以找到一种方法来翻译处理序列的循环。但是这个怎么样?我怎么用clojure的方式写呢?使用map、reduce等,而不是循环重复出现。

对于扩展的欧几里德算法,您可以使用简单的递归,这使函数看起来非常优雅:

(defn extended-gcd [a b]
  (if (zero? b) [1 0]
    (let [[q r] [(quot a b) (rem a b)]
          [s t] (extended-gcd b r)] 
      [t (- s (* q t))])))
让我们试试看:

user=> (extended-gcd 120 23)
[-9 47]

并非所有问题都需要使用map/reduce/sequence来解决。我认为,上述方法与您正在寻找的“
(reduce+[1 2 3 4 5])
”类型的答案一样简单。

对于此类问题,迭代通常是使用循环的一个很好的替代方法。在这种情况下,它将导致对源算法进行相当透明的转换:

(defn extended-gcd [a b]
  (->> {:a a, :b b, :x 0, :y 1, :lx 1, :ly 0}
    (iterate 
      (fn [{keys [a b x y lx ly]}]
        (let [q (quot a b)]
          {:a b, :b (mod a b), :x (- lx (* q x)), :lx x, :y (- ly (* q y)), :ly y})))
    (drop-while #(not= 0 (:b %)))
    first
    ((juxt :lx :ly))))
也就是说,使用循环也是一种Clojure方式——我认为,避免使用循环的警告是为了鼓励在更合适的地方使用更高级的结构

(defn extended-gcd [a b]
  (->> {:a a, :b b, :x 0, :y 1, :lx 1, :ly 0}
    (iterate 
      (fn [{keys [a b x y lx ly]}]
        (let [q (quot a b)]
          {:a b, :b (mod a b), :x (- lx (* q x)), :lx x, :y (- ly (* q y)), :ly y})))
    (drop-while #(not= 0 (:b %)))
    first
    ((juxt :lx :ly))))