我试图编写一个名为rotate-right
的函数(: rotate-right : (All (A) (Vectorof A) Integer Integer -> Void))
(rotate right v lo hi)
修改向量v,使得区间[lo..hi-1]中的元素移动到位置[lo + 1..hi]并且将索引hi处的元素移动到位置lo。例如
(rotate-right (vector 0 1 2 3 4 5 6 7 8 9))
产生
#(0 1 5 2 3 4 6 7 8 9).
我已经写了这段代码
(: rotate-right : (All (a) (Vectorof a) Integer Integer -> Void))
(define (rotate-right v lo hi)
(local
{(define tmp v)
(: vector-scan : (All (a) (Vectorof a) Integer Integer Integer -> Void))
(define (vector-scan v lo hi c)
(cond
[(= c -1) (vector-set! v 0 (vector-ref v 0))]
[(and (< lo c) (>= hi c))
(vector-scan
(vector-set! v c (vector-ref tmp (- c 1)))
lo hi (- c 1))]
[(= c lo)
(vector-scan
(vector-set! v lo (vector-ref tmp hi))
lo hi (- c 1))]
[else
(vector-scan
(vector-set! v c (vector-ref v c))
lo hi (- c 1))]))}
(vector-scan v lo hi (vector-length v))))
然而,这给了我vector-set!的类型错误。谁能告诉我我做错了什么?感谢。
答案 0 :(得分:1)
我无法帮助您使用键入的部分,但您的算法也无法在常规的Racket中使用。写一个更简洁的方法(同时保持使用索引)将是:
(define (rotate-right v lo hi)
(for/vector ((i (in-range (vector-length v))))
(vector-ref v
(cond
((< i lo) i)
((= i lo) hi)
((<= i hi) (sub1 i))
(else i)))))
然后
> (rotate-right (vector 0 1 2 3 4 5 6 7 8 9) 2 5)
'#(0 1 5 2 3 4 6 7 8 9)
答案 1 :(得分:1)
以下是for
的版本。
#lang typed/racket
(: rotate-right : (All (A) (Vectorof A) Integer Integer -> Void))
(define (rotate-right v lo hi)
(define hi-1 (- hi 1))
(cond
[(>= lo hi-1) (void)]
[else (define tmp (vector-ref v hi-1))
(for ([i (in-range hi-1 lo -1)])
(vector-set! v i (vector-ref v (- i 1))))
(vector-set! v lo tmp)]))
(define v (vector 0 1 2 3 4 5 6 7 8 9))
(rotate-right v 3 7)
v
输出结果为:
'#(0 1 2 6 3 4 5 7 8 9)
问题是我们如何修复原始程序。
矢量集!返回void,我们需要分开调用
到vector-set!
和vector-scan
。
此外,矢量扫描的类型应该重用类型变量a 来自旋转a。
这给出了以下具有正确类型的程序。 (我还没有测试它是否正确旋转)。
(: rotate-right : (All (a) (Vectorof a) Integer Integer -> Void))
(define (rotate-right v lo hi)
(local
{(define tmp v)
(: vector-scan : (Vectorof a) Integer Integer Integer -> Void)
(define (vector-scan v lo hi c)
(cond
[(= c -1) (vector-set! v 0 (vector-ref v 0))]
[(and (< lo c) (>= hi c))
(vector-set! v c (vector-ref tmp (- c 1)))
(vector-scan v lo hi (- c 1))]
[(= c lo)
(vector-set! v lo (vector-ref tmp hi))
(vector-scan v lo hi (- c 1))]
[else
(vector-set! v c (vector-ref v c))
(vector-scan v lo hi (- c 1))]))}
(vector-scan v lo hi (vector-length v))))