2

这个问题有多种形式。例如,给定输入 '(1 2 3 4 5 6),我们可能希望交换偶数和奇数对之间的值。输出将是'(2 1 4 3 6 5)。

在 Haskell 中,这相当简单:

helper [] = []
helper [x] = [x]
helper (x : y : ys) = y : x : helper ys

我写了一些 Clojure 代码来完成相同的任务,但我觉得可能有一种更清洁的方法。关于如何改进这一点的任何建议?

(defn helper [[x y & ys]]
  (cond
   (nil? x) (list)
   (nil? y) (list x)
   :else (lazy-seq (cons y (cons x (helper ys))))))

理想情况下,列表会被懒惰地消耗和产生。谢谢。

4

3 回答 3

4
(for [[a b] (partition 2 '(1 2 3 4 5 6))
      i [b a]]
  i)

或者类似于haskell版本的东西:

(defn helper
  ([] (list))
  ([x] (list x))
  ([x y & r] (concat [y x] (apply helper r))))

(apply helper '(1 2 3 4 5 6))
于 2013-07-11T04:23:42.563 回答
3

这是一种懒惰的方法:

user=> (mapcat reverse (partition 2 '(1 2 3 4 5 6)))
(2 1 4 3 6 5)
于 2013-07-11T03:23:53.580 回答
3

在处理输入中的项目时避免中间对象创建(要连接的向量/序列)并与 Haskell 原始对象直接对应nil(问题文本中的方法不这样做):

(defn helper [[x & [y & zs :as ys] :as xs]]
  (if xs
    (lazy-seq
      (if ys
        (cons y (cons x (helper zs)))
      (list x)))))

通常我会使用类似汤姆的答案,但只能使用mapcat而不是flatten

(defn helper [xs]
  (mapcat reverse (partition-all 2 xs)))

您需要使用partition-all而不是partition避免从奇数长度的列表中删除最终元素。

于 2013-07-11T05:13:48.300 回答