【发布时间】: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