list - clojure - 2 个列表的有序成对组合

标签 list clojure combinations

作为 clojure 的新手,我仍然在为它的功能而苦苦挣扎。如果我有 2 个列表,比如“1234”和“abcd”,我需要制作所有可能的长度为 4 的有序列表。我想要的长度为 4 的输出是:

("1234" "123d" "12c4" "12cd" "1b34" "1b3d" "1bc4" "1bcd" 
 "a234" "a23d" "a2c4" "a2cd" "ab34" "ab3d" "abc4" "abcd")

其中 2^n 的数量取决于输入。

我编写了以下函数来通过随机游走生成单个字符串/列表。
参数 [par] 类似于 ["1234""abcd"]
(defn make-string [par] (let [c1 (first par) c2 (second par)] ;version 3 0.63 msec
  (apply str (for [loc (partition 2 (interleave c1 c2)) 
                   :let [ch (if (< (rand) 0.5) (first loc) (second loc))]] 
                     ch))))

输出将是上面 16 个有序列表中的 1 个。两个输入列表中的每一个都将始终具有相等的长度,例如 2,3,4,5,直至 2^38 或在可用内存内。在上面的函数中,我试图修改它以生成所有有序列表但失败了。希望有人可以帮助我。谢谢。

最佳答案

Mikera 是正确的,您需要使用递归,但是您可以在更简洁和更通用的情况下做到这一点 - 当您可以使用 N 个序列时,为什么要使用两个字符串?

(defn choices [colls]
  (if (every? seq colls)
    (for [item (map first colls)
          sub-choice (choices (map rest colls))]
      (cons item sub-choice))
    '(())))

(defn choose-strings [& strings]
  (for [chars (choices strings)]
    (apply str chars)))

user> (choose-strings "123" "abc")
("123" "12c" "1b3" "1bc" "a23" "a2c" "ab3" "abc")

这种递归的nested-for 是一种非常有用的模式,用于通过选择“树”创建一系列路径。无论是实际的树,还是一遍又一遍地重复相同的选择,或者(如这里)不依赖于先前选择的一组 N 个选择,这都是一个可用的方便工具。

关于list - clojure - 2 个列表的有序成对组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9903179/

相关文章:

performance - clojure 多方法天生慢吗

Clojure 按过滤器分区

python - 两个列表值的组合

c# - 排序列表或二叉搜索树

python - 获取一个列表并返回有序对中的随机元素(必须是可变的)

list - 如何将两个列表 append 在一起?方案

clojure - 在 repl 中获取当前 clojure 项目的版本

python - 基于字符列表的单词组合

haskell - 在 Haskell 中迭代所有对组合而不重复

c++ - 段列表迭代器错误 C++