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
by

幂集是集合论中的数学问题/解决方案。
如果你理解了这个问题和解决方案,你就可以用任何语言将其写出来。

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

对于这种问题的解决方案,我通常会查找 Java 库,大多数情况下,那里已经存在一些你可以直接使用的东西,它已经被调试并且优化得很好。

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))

组合数学中Clojure的解决方案与维基百科中Python的一个解决方案更接近,它使用组合来生成子集。

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

Java解决方案通过对不同组合可以表示为二进制数的事实进行优化,非常优秀。

by
要打印值,可以使用string join和一个doseq

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

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


  如果你想要去掉空集,可以使用filter。

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