请在2024年Clojure调查问卷中分享您的想法!

欢迎!请查看关于页面,了解更多关于这个网站的信息。

0
Clojure

我有一个任务,需要创建一个函数,该函数可以给出列表的全集。

列表(1 2 3)的输出应该是这样的

1
2
3
1 2
1 3
2 3
1 2 3
我尝试了这个辅助函数

(defn print-powerset-helper [lst] (if(not(empty? lst)) (do (println(first lst)) (print-lst (rest lst)))))
它给了我

1
2
3
nil
这个输出。

我还尝试了这个函数

(defn print-powerset [lst] (if (not (empty? lst)) (do (apply println lst (print-lst lst)))))
输出

1
2
3
(1 2 3)
nil
我想去掉括号,并且不明白如何打印输出中间的部分。1 2 1 3 2 3 ,这部分。

请尽一切帮助,非常感谢!

2 个答案

+1

全集是集合论中的一个数学问题和解决方案。
如果你理解了这个问题和解决方案,你就可以在任何语言中编写出来。

请参见:https://en.wikipedia.org/wiki/Power_set

对于这类问题,我通常在Java库中查找,99% 的情况下,已经有现成的东西可以供你使用,而且是经过充分调试和优化的。

https://guava.dev/releases/20.0/api/docs/com/google/common/collect/Sets.html#powerSet-java.util.Set-

如果你想看到另一个Java解决方案,可以看这个
https://www.geeksforgeeks.org/finding-all-subsets-of-a-given-set-in-java/

对于纯clojure解决方案,请看
你可以使用:https://github.com/clojure/math.combinatorics/

 (require '[clojure.math.combinatorics :as combo])
 (combo/subsets [1 2 3])
 >> (() (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3))

combinatorics中的clojure解决方案更接近维基百科中的python解决方案,并使用组合生成子集。

https://github.com/clojure/math.combinatorics/blob/master/src/main/clojure/clojure/math/combinatorics.cljc#L218

Java解决方案通过利用不同组合可以被表示为二进制数这一事实,进行了相当优化的处理。

by
要打印值,可以使用字符串连接符和序列。

  (require '[clojure.math.combinatorics :as combo])
  (require '[clojure.string :as s])

  (doseq [l (combo/subsets [1 2 3])]
      (println (s/join ",", l)))


  如果你想要去除空集,请使用过滤器。

  (doseq [l (filter (complement empty?)  
                                           (combo/subsets [1 2 3]))]
       (println (s/join ",", l)))
0
by
by
不错。第二个回答中的实现让我印象深刻: https://gist.github.com/anonymous/796299
...