2014-12-02 7 views
1

I은 ​​벡터 V를 수정 회전 오른쪽형식화 라켓 오류 벡터 세트

(: rotate-right : (All (A) (Vectorof A) Integer Integer -> Void)) 
(rotate right v lo hi) 

라는 함수를 작성하는 것을 시도하고되도록하는 간격의 요소 [lo..hi-1] 위치 [lo + 1..hi]로 이동되고 인덱스 hi의 요소는 위치 lo로 이동합니다. 예를

를 들어
(rotate-right (vector 0 1 2 3 4 5 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)))) 

에게 서면으로 작성했습니다

#(0 1 5 2 3 4 6 7 8 9). 

는이 날 벡터가 세트로 오류를 입력 할 수 있습니다 생산! 아무도 내가 뭘 잘못하고 있다고 말할 수 있습니까? 감사.

답변

1

입력 된 부분은 도움이되지 않지만 알고리즘은 일반 라켓에서도 작동하지 않습니다. (당신이로 인덱스를 사용하여 유지하면서) 더 간결 방법은 것이 쓰기 :

(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

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 을 다시 사용해야합니다.

그러면 올바른 유형의 다음 프로그램이 제공됩니다. (제대로 회전하는지 테스트하지 않았습니다).

(: 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))))