Recursion 将python代码转换为clojure、递归和for循环

Recursion 将python代码转换为clojure、递归和for循环,recursion,clojure,Recursion,Clojure,我从一个长度为n的列表中计算出n中的k。我发现python代码非常简洁,所以我做了直接翻译 def comb(sofar, rest, n): if n == 0: print sofar else: for i in range(len(rest)): comb(sofar + rest[i], rest[i+1:], n-1) comb("", "abcde", 3) 产量: abc、abd、abe等 将被

我从一个长度为n的列表中计算出n中的k。我发现python代码非常简洁,所以我做了直接翻译

def comb(sofar, rest, n):
     if n == 0:
         print sofar
     else:
         for i in range(len(rest)):
             comb(sofar + rest[i], rest[i+1:], n-1)

comb("", "abcde", 3)
产量: abc、abd、abe等

将被转换为clojure代码:

(defn comb [sofar v n]
  (if (= n 0)
    (print sofar)
    (for [i (range 0 (count v))] 
      (comb  (str sofar (nth v i))   ;don't it need to be recur ?
             (subvec v (inc i))
             (dec i)))))
嵌套循环/递归相当混乱

问题是如何更改代码以执行与python代码相同的功能


我的clojure代码似乎做不到同样的工作。

首先,如果您想要clojure解决方案,请考虑clojure术语,在生成惰性序列的序列上编写函数,并让最终使用者在需要时将其减少为字符串。在下面,我根本不使用print,只返回惰性序列,让repl作为打印机

另外,您正在尝试将python
for
直接转换为clojure
for
to循环,这不是它的目的(没有双关语)。是一个序列发生器,所以你可能会感到困惑

要获得问题的简单解决方案,您可以使用:

然后,如果需要,您可以编写一个映射,将其转换为字符串,以获得与python相同的输出

user=> (map #(apply str %1) (m/combinations "abcde" 3))
("abc" "abd" "abe" "acd" "ace" "ade" "bcd" "bce" "bde" "cde")
然而,我怀疑您正在寻找更多关于循环的教程

创建一个函数以chars形式返回序列是非常困难的,它会生成与上面示例相同的序列,并且也可以包装在映射中用于字符串输出。它使用带有cond块的递归来控制迭代的结束

通过将问题解构成某种本质上是递归的东西来解释它如何与递归一起工作

如果您想了解有关递归与命令式循环的更多信息,请查看以下内容

通过一些阶乘循环/递归与递归的例子,您可以直接看到两者之间的语法风格

就习惯于编写生成这样的序列的函数而言,我发现这是解释思维过程的极好资源。它是用scheme编写的,但很容易理解并应用于clojure。在此之后,您可以查看高阶函数(map/reduce),而不是使用循环


总而言之,在这样做的时候,如果你到处都使用惰性函数,你的结果通常是惰性的,如果你进行递归,你想尝试使用尾部递归,这样在使用大组合时就不会破坏堆栈,也不会转储你不感兴趣的值。

那么,你有什么特别的问题吗?JFYI,stackoverflow不是免费的在线代码翻译工具。@zerkms我也在练习clojure。烧掉脑袋来得到一些干净的代码。你的问题几乎没问题,CodeFarmer。只要解释一下Clojure版本中出现了什么问题。这将有助于回答问题的人,并避免抱怨。对于不深入的递归,
recurr
。但是,如果您的代码是尾部递归的,
recur
将更有效,并且它将允许深度递归。
user=> (map #(apply str %1) (m/combinations "abcde" 3))
("abc" "abd" "abe" "acd" "ace" "ade" "bcd" "bce" "bde" "cde")