在我正在进行的一个项目中,我遇到了一个有趣的问题,我对其他解决方案感到好奇。我正在阅读“The Little Schemer”,所以我正在尝试一些递归技术。我想知道是否有另一种使用递归的方法来做到这一点,并且如果有一种不使用递归的方法也很感兴趣。
问题是获取一个序列,并通过获取每个第 n 个元素将其划分为一个 seq 序列。例如这个向量:
[ :a :b :c :d :e :f :g :h :i ]
当用 n=3 分区时会产生 seq
((:a :d :g) (:b :e :h) (:c :f :i))
n = 4:
((:a :e :i) (:b :f) (:c :g) (:d :h))
等等。我使用两个函数解决了这个问题。第一个创建内部序列,另一个将它们拉在一起。这是我的功能:
(defn subseq-by-nth
"Creates a subsequence of coll formed by starting with the kth element and selecting every nth element."
[coll k n]
(cond (empty? coll) nil
(< (count coll) n) (seq (list (first coll)))
:else (cons (nth coll k) (subseq-by-nth (drop (+ n k) coll) 0 n))))
(defn partition-by-nth
""
([coll n]
(partition-by-nth coll n n))
([coll n i]
(cond (empty? coll) nil
(= 0 i) nil
:else (cons (subseq-by-nth coll 0 n) (partition-by-nth (rest coll) n (dec i))))))
我对仅用于递归的具有多个参数的逐个分区函数并不完全满意,但看不到另一种方式。
这似乎适用于所有测试用例。这是一个体面的方法吗?是不是太复杂了?有没有办法在没有递归的情况下或者在单个递归函数中做到这一点?
感谢您的建议。我是 Clojure 和 Lisp 的新手,所以我在学习不同的技术。