【问题标题】:Sorting a 2d-vector by index value into lazy sequence in clojure在clojure中按索引值将二维向量排序为惰性序列
【发布时间】:2012-01-19 02:57:45
【问题描述】:

我正在阅读 Clojure 的乐趣,并遇到了一个快速排序的实现,它使用惰性序列来实现比 O(n log n) 更好的性能,当只从惰性序列中获取前几个 cons 单元格时。我试图让它为一个二维整数数组工作,但我似乎不太明白: 到目前为止,这就是我所拥有的:

(defn sort-parts2
  "Lazy, tail-recursive, incremental quicksort. Works against
   and creates partitions based on the pivot, defined as 'work'."
  [work]
  (lazy-seq
    (loop [[part & parts] work]
      (if-let [[pivot & xs] (seq part)]
        (let [smaller? #(< % pivot)]
          (recur (list*
                 (filter smaller? xs)
                 pivot
                 (remove smaller? xs)
                 parts)))
      (when-let [[x & parts] parts] 
      (cons x (sort-parts2 parts)))))))



   sort.joy=> a
    [[5 9 0 6 5 1 4 4 8 7]
     [2 6 8 2 6 7 0 1 8 1]
     [8 8 0 5 9 9 7 7 1 6]
     [9 8 5 3 0 2 0 6 9 3]
     [8 8 5 8 9 8 2 3 8 5]
     [7 9 2 8 5 6 6 8 3 4]
     [4 8 2 4 6 6 7 4 4 1]
     [8 5 1 7 3 0 2 4 2 3]
     [9 1 2 9 0 1 0 2 2 9]
     [4 0 2 6 8 5 6 1 7 7]]

对于子向量第一个元素上的(sort-parts2 a 0) //index 的输入,我想要得到的是:

   sort.joy=> aSorted
     [[2 6 8 2 6 7 0 1 8 1]
     [4 0 2 6 8 5 6 1 7 7]
     [4 8 2 4 6 6 7 4 4 1]
     [5 9 0 6 5 1 4 4 8 7]
     [7 9 2 8 5 6 6 8 3 4]
     [8 5 1 7 3 0 2 4 2 3]
     [8 8 0 5 9 9 7 7 1 6]
     [8 8 5 8 9 8 2 3 8 5]
     [9 1 2 9 0 1 0 2 2 9]
     [9 8 5 3 0 2 0 6 9 3]]

按原样,这就是我现在得到的:

sort.joy=> (sort-parts a)
(0
 1
 4
 4
 5
 5
 6
 7
 8
 9
 [2 6 8 2 6 7 0 1 8 1]
 0
 1
 5
 6
 7
 7
 8
 8
 9
 9
 [9 8 5 3 0 2 0 6 9 3]
 2
 3
 5
 5
 8
 8
 8
 8
 8
 9
 [7 9 2 8 5 6 6 8 3 4]
 1
 2
 4
 4
 4
 4
 6
 6
 7
 8
 [8 5 1 7 3 0 2 4 2 3]
 0
 0
 1
 1
 2
 2
 2
 9
 9
 9
 [4 0 2 6 8 5 6 1 7 7])

有人可以帮我找出一种方法来阻止循环完全解构二维向量,从而返回一个头部为行向量的惰性向量吗?我已经找出了行的比较器,谢谢!

edit 更一般的问题表述:我想将一个二维向量排序为一个惰性序列,如下面的a,其中头部是下一个由指数。为了不懒惰地做到这一点,我正在使用:

(defn sortVector 
  "sorts a 2d vector by the given index"
  [index coll]
  (sort-by #(nth % index) coll))

【问题讨论】:

    标签: sorting clojure lazy-evaluation


    【解决方案1】:

    如果您从原始代码开始并将smaller? 函数替换为比较pivot 和另一项上的某个关键函数的值的函数,则可以从JoC 代码派生sort-parts-by 函数,而不是直接物品:

    (let [pivot-key (keyfn pivot)
          smaller? #(.compare ^java.util.Comparator comp
                              (keyfn %1)
                              pivot-key)]
      ...)
    

    名称 keyfncomp 来自 clojure.core/sort-by - 请参阅其文档字符串/实现以了解预期含义。

    请注意,sort-parts 并不打算在要排序的实际序列上调用——您必须首先将其包装在某种 seqable 中(可能是向量);例如,参见 JoC 中qsort 的定义。您可能希望qsort-by 与上面概述的功能一起使用。

    【讨论】:

      猜你喜欢
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2010-12-08
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多