我正在阅读“欢乐的Clojure”,并且遇到了一种快速排序的实现,它使用惰性序列来实现比仅使用延迟序列中的前几个cons细胞时的O(n log n)性能更好的性能。我试图让它为2d数组的整数工作,但我似乎无法得到它: 到目前为止,这就是我所拥有的:
(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)
//索引是:
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])
有人可以帮我找出一种方法来阻止循环完全解构2d向量,从而返回一个懒惰的向量,头部是行向量吗?我找到了行的比较器,谢谢!
编辑问题的更一般的表述:我想对一个2d向量进行排序,将a
看作是一个懒惰的序列,其中头部是下一个有序的子向量通过索引。为了非懒惰,我正在使用:
(defn sortVector
"sorts a 2d vector by the given index"
[index coll]
(sort-by #(nth % index) coll))
答案 0 :(得分:1)
如果您从原始文件开始,可以从JoC代码派生sort-parts-by
函数,并将smaller?
函数替换为比较pivot
上某些关键函数的值的函数。另一个项目,而不是直接项目:
(let [pivot-key (keyfn pivot)
smaller? #(.compare ^java.util.Comparator comp
(keyfn %1)
pivot-key)]
...)
名称keyfn
和comp
来自clojure.core/sort-by
- 请参阅其文档字符串/实现以获取预期含义。
请注意,sort-parts
不是要在要排序的实际序列上调用 - 你必须首先将它包装在某种seqable中(可能是一个向量);有关示例,请参阅JoC中qsort
的定义。您可能希望qsort-by
与上面概述的功能一起使用。