作为 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/