2016-11-09 67 views
1

當這樣寫的錯誤說:後4個部分,如果:如何使用球拍/方案建立滾動窗口程序?

(define (rolling-window l size) 
    (if (< (length l) size) l 
    (take l size) (rolling-window (cdr l) size))) 

,當有另一個paranthesis,使其3個部分:

(define (rolling-window l size) 
    (if (< (length l) size) l 
    ((take l size) (rolling-window (cdr l) size)))) 

然後它說:應用程序:不是一個程序;

+0

https://docs.racket-lang.org/reference/if.html – coredump

+1

使用'cond'。或者,用'begin'或'let'封裝分支,但使用'cond'可能更容易。 –

+0

(取l尺寸)(滾動窗口(cdr l)尺寸) 應該在else部分不需要第三個替代方案 – X10D

回答

3

如何在if/else中寫入多個表達式在球拍/方案中?

那麼這不是真正的問題。問題是「如何使用球拍建立滾動窗口程序?」。無論如何,看起來你可能來自另一種編程語言。處理鏈表首先可能有點棘手。但請記住,要計算列表的長度,您必須遍歷整個列表。所以在這裏使用length是一個反模式。

相反,我會建議您在rolling-window過程中創建一個aux iliary過程,在遍歷列表時構建窗口。這樣您就不必浪費迭代計算列表中的元素。

然後,如果您的aux過程返回並且爲空窗口,那麼您知道您已完成計算給定輸入列表的窗口。

(define (rolling-window n xs) 
    (define (aux n xs) 
    (let aux-loop ([n n] [xs xs] [k identity]) 
     (cond [(= n 0) (k empty)] ;; done building sublist, return sublist 
      [(empty? xs) empty] ;; reached end of xs before n = 0, return empty window 
      [else (aux-loop (sub1 n) (cdr xs) (λ (rest) (k (cons (car xs) rest))))]))) ;; continue building sublist 

    (let loop ([xs xs] [window (aux n xs)] [k identity]) 
    (cond ([empty? window] (k empty)) ;; empty window, done 
      ([empty? xs] (k empty))  ;; empty input list, done 
      (else (loop (cdr xs) (aux n (cdr xs)) (λ (rest) (k (cons window rest)))))))) ;; continue building sublists 

(rolling-window 3 '(1 2 3 4 5 6)) 
;; => '((1 2 3) (2 3 4) (3 4 5) (4 5 6)) 

它適用於空窗

(rolling-window 0 '(1 2 3 4 5 6)) 
;; => '() 

而空列表太

(rolling-window 3 '()) 
;; => '() 
+0

一個非常好的解決方案。一個小小的評論:因爲循環不會修改'n',所以它可以被排除在參數列表之外。 – soegaard

+0

@soegaard謝謝你的支持! – naomik

+0

xs的詞源是什麼? – X10D

2

這裏是一個另類:

#lang racket 

(define (rolling-window n xs) 
    (define v (list->vector xs)) 
    (define m (vector-length v)) 
    (for/list ([i (max 0 (- m n -1))]) 
    (vector->list (vector-copy v i (+ i n))))) 

(rolling-window 3 '(a b c d e f g)) 
(rolling-window 3 '()) 
(rolling-window 0 '(a b c)) 

輸出:

'((a b c) (b c d) (c d e) (d e f) (e f g)) 
'() 
'(()()()()) ; lack of spec makes this ok ! 
1

下面對OP功能的修改進行了修改。它包括一個outlist,初始默認爲空列表。子列表被添加到此列表中,直到(length l)小於size

(define (rolling-window l size (ol '())) 
    (if (< (length l) size) (reverse ol) 
     (rolling-window (cdr l) size (cons (take l size) ol)))) 

測試:

(rolling-window '(1 2 3 4 5 6) 2) 
(rolling-window '(1 2 3 4 5 6) 3) 
(rolling-window '(1 2 3 4 5 6) 4) 

輸出:

'((1 2) (2 3) (3 4) (4 5) (5 6)) 
'((1 2 3) (2 3 4) (3 4 5) (4 5 6)) 
'((1 2 3 4) (2 3 4 5) (3 4 5 6)) 
0

在這一個任何改進?

(define (rolling-window l size) 
    (cond ((eq? l '()) '()) 
     ((< (length l) size) '()) 
     ((cons (take l size) (rolling-window (cdr l) size))))) 
+0

我已經告訴過你'長度'是一個反模式 – naomik

+0

1:這將是很好的擺脫長度檢查。用任何方式組合take函數,以便在列表不夠長的時候靜靜地退出,而不是拋出列表太短的錯誤? 2:是的,它效率較低,但可讀性更強一點? – X10D