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-powerset-helper (rest lst)))))
它给我

1
2
3
nil
这样的输出。

我还试了这个函数

(defn print-powerset [lst] (if (not (empty? lst)) (do (apply println lst (print-powerset 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))

组合学中的Clojure解决方案接近维基百科中Python的解决方案,并使用组合来生成子集。

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

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

要打印值,可以使用字符串连接和doseq

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

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


  如果你想要删除空集,可以使用filter。

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