有没有更好的方法来编写将元素插入clojure中的排序列表的代码?

有没有更好的方法来编写将元素插入clojure中的排序列表的代码?,clojure,Clojure,我正在做星期六的练习7。我有一个解决方案,但是因为预期的输出是一个列表,所以我不得不在一些输出中添加一个“反向”。这似乎有点老套 这是我的密码: (defn insert [sorted-seq n] (loop [output () my-seq sorted-seq] (cond (nil? (first my-seq)) (conj output n) (nil? (first (rest my-seq)))

我正在做星期六的练习7。我有一个解决方案,但是因为预期的输出是一个列表,所以我不得不在一些输出中添加一个“反向”。这似乎有点老套

这是我的密码:

(defn insert [sorted-seq n]
  (loop [output ()
         my-seq sorted-seq]
    (cond 
     (nil? (first my-seq)) 
       (conj output n)
     (nil? (first (rest my-seq))) 
       (reverse (conj output (first my-seq) n))
     :else
      (if (> (first (rest my-seq)) n (first my-seq))
        (reverse (apply conj output (first my-seq) n (rest my-seq)))
        (recur (conj output (first my-seq)) (rest my-seq))))))

(insert [] 2)      ;=> (2)
(insert [1 3 4] 2) ;=> (1 2 3 4)
(insert [1] 2)     ;=> (1 2)

有没有更好的方法来写这篇文章,更有效,并且不需要反转输出?另外,前两个条件似乎很笨拙。有更好的方法吗?

@a.Webb的解决方案就是您正在寻找的解决方案,但留给未来的访问者

我认为你稍微把问题复杂化了

总体思路是:

  • 找到需要插入元素的站点
  • 在该点将序列一分为二
  • 连接第一个结果序列、元素和第二个结果序列
  • 您可以使用组合1和2,这将序列分为两部分:一部分谓词为true,另一部分谓词为false

    所以说clojure:

    (defn insert [coll n]
       (let [[l r] (split-with #(< % n) coll)]
           (concat l [n] r))
    
    (定义插入[coll n]
    (让[[l r](与#(<%n)coll分割)]
    (concat l[n]r))
    
    我认为练习的重点是使用递归,而不一定是生成最惯用的代码。您可以通过使用一个数据结构来避免反转,该数据结构的右边是一个向量

    (defn insert [sorted-seq n]
      (loop [s sorted-seq, a []]
        (cond 
          (empty? s)       (conj a n)
          (< (first s) n)  (recur (rest s) (conj a (first s)))
          :else            (apply conj a n s))))
    
    (定义插入[排序顺序n]
    (循环[s排序顺序,a[]
    (续)
    (空的?s)(连体)
    (<(第一个s)n)(重复(剩余s)(合并a(第一个s)))
    :else(应用conj a n s)))
    
    只要您准备好使用适当的递归,就可以通过一个列表简单地完成这项工作:

    (defn insert [ss n]
      (if (empty? ss)
        (list n)
        (let [[x & xs] ss]
          (if (< n x)
            (cons n ss)
            (cons x (insert xs n))))))
    
    (定义插入[ss n]
    (如果(空?ss)
    (列表n)
    (让[[x&xs]ss]
    (如果(
    • 如果你想让身体长时间工作,就用一个
      lazy seq
      来包装身体 不吹堆栈的序列
    • 它仍然会比以前慢很多

    我猜与3的比较应该是n?@soulcheck我们还没有讨论过split,但我会检查一下。它看起来很方便。谢谢。@jbrown是的,如果不是递归中的练习,你可能会使用它。如果这不是练习,你根本不会使用排序列表:它们对于任务来说是一个糟糕的数据结构。排序集,或用作多集、堆或其他东西的排序映射都是更好的选择。是的,你说得对。我浏览了其余的问题,没有注意到重复部分。我使用了一个向量,但随后注意到输出是一个列表。我想知道为什么会这样-也许我应该使用一个函数。也许re毕竟不是理由……但谢谢。我的条件太多了。你的条件要简洁得多。