Vector 合并向量排序
我试图在Scheme中使用向量实现mergesort算法。我知道我可以使用其他排序方法,但我想在这方面完成我的代码。到目前为止,我掌握的情况如下Vector 合并向量排序,vector,scheme,mergesort,Vector,Scheme,Mergesort,我试图在Scheme中使用向量实现mergesort算法。我知道我可以使用其他排序方法,但我想在这方面完成我的代码。到目前为止,我掌握的情况如下 (define (split v) (define (helper k v1 v2) (let ((m (floor (/ (vector-length v) 2)))) (if (>= k m) (if (= k (vector-length v)
(define (split v)
(define (helper k v1 v2)
(let ((m (floor (/ (vector-length v) 2))))
(if (>= k m)
(if (= k (vector-length v))
(cons v1 v2)
(helper (+ k 1) v1 (vector-append v2 (vector (vector-ref v k)))))
(helper (+ k 1) (vector-append v1 (vector (vector-ref v k))) v2))))
(helper 0 #() #()))
(define (merge v1 v2)
(if (< (vector-ref v1 0) (vector-ref v2 0))
(vector-append v1 v2)
(vector-append v2 v1)))
(define (mergesort v)
(if (<= (vector-length v) 1)
v
(merge (mergesort (car (split v))) (mergesort (cdr (split v))))))
(定义(拆分v)
(定义(辅助程序k v1 v2)
(让((m(地板(/(向量长度v)2)))
(如果(>=km)
(如果(=k(矢量长度v))
(cons v1 v2)
(helper(+k1)v1(向量附加v2(向量(向量参考v k ')))))
(辅助对象(+k1)(向量附加v1(向量(向量引用vk)))v2)))
(助手0#()#())
(定义(合并v1 v2)
(如果(<(矢量参考v1 0)(矢量参考v2 0))
(矢量附加v1 v2)
(矢量附加v2 v1)))
(定义(合并排序v)
(如果(实现的主要障碍是merge
函数没有正确实现合并算法。在合并算法中:
您有两个指针,它们最初指向左侧和右侧列表的开头
如果两个指针都在各自列表的末尾,那么就完成了
如果任一指针位于其各自列表的末尾,则输出另一个列表的其余元素。完成
此时,两个指针都指向一个元素。如果右侧元素小于左侧元素,则输出右侧元素,并前进右侧指针。否则,输出左侧元素,并前进左侧指针。转至步骤2
下面我的合并到!
函数实现了这种方法
除此之外,另一个主要问题是你的split
函数试图逐段构建向量,不幸的是,这是一个缓慢的过程:它每次都必须将所有元素复制到一个新的向量中。这不像cons
!对于向量,不要犹豫使用向量集!
;任何不可变的向量更新都是无效的这将是缓慢而低效的,所以只要咬紧牙关,让它变为可变的。:-)
作为参考,我从头开始编写了一个新的实现(在Racket中):
如果你不使用球拍,你可能需要以下额外的定义(这需要;如果你没有,请参阅文章底部):
let values
是在中定义的。如果您没有,这里有一个版本的mergesort
,它使用调用值
:
(define (mergesort vec)
(case (vector-length vec)
((0 1) vec)
(else (call-with-values (lambda () (split-halves vec))
(lambda (lhs rhs)
(merge (mergesort lhs) (mergesort rhs)))))))
矢量复制
是在中定义的。如果您没有,这里有一个简化版本:
(define (vector-copy vec start end)
(define result (make-vector (- end start)))
(do ((i start (+ i 1))
(j 0 (+ j 1)))
((>= i end) result)
(vector-set! result j (vector-ref vec i))))
不,你不会“在编码方面很差劲”。-)只是向量与链表有很大的不同,处理它们的编码技术也有很大的不同。因为向量很少在Scheme中使用,所以没有很多Scheme书籍和网站能够很好地处理向量;他们通常认为,如果你使用它们,你已经知道如何正确使用它们了在你随后的问题中看到了你的评论,我知道你觉得我在屈尊于你的编码。我的回答可能有点太直截了当了,对此我深表歉意。直接反馈是我在工作中做的代码审查中的一个习惯——在工作中,我们有一个政策,即每个代码签入都必须经过同行审查,因此ou中的每个人r团队审查了很多代码,多年来,我开发了一种特定的审查风格。很抱歉,事后看来,这不是你想要的,我把你的问题当作代码审查。谢谢你,克里斯;我删除了编辑。我看到了你的一些其他论坛帖子,我知道你非常擅长你的工作。我有人能在几分钟内解决我遇到的问题,而我花了一两个小时来解决这个问题。我只需要多练习。现在轮到我忏悔了。1.我的计划水平远不及伊莱·巴兹利,我对他做了真正困难的事。:-)2。我从2002年就开始使用Scheme,所以我在这方面做了很多练习。我有信心,在11年后,你可能会比我更有经验。
(define (vector-split-at vec pos)
(values (vector-copy vec 0 pos)
(vector-copy vec pos (vector-length vec))))
(define (add1 x)
(+ x 1))
(define (mergesort vec)
(case (vector-length vec)
((0 1) vec)
(else (call-with-values (lambda () (split-halves vec))
(lambda (lhs rhs)
(merge (mergesort lhs) (mergesort rhs)))))))
(define (vector-copy vec start end)
(define result (make-vector (- end start)))
(do ((i start (+ i 1))
(j 0 (+ j 1)))
((>= i end) result)
(vector-set! result j (vector-ref vec i))))