Functional programming 如何使用racket/scheme构建滚动窗口过程?

Functional programming 如何使用racket/scheme构建滚动窗口过程?,functional-programming,scheme,racket,Functional Programming,Scheme,Racket,以这种方式写入时,错误显示:如果: (define (rolling-window l size) (if (< (length l) size) l (take l size) (rolling-window (cdr l) size))) (定义(滚动窗口l大小) (如果(

以这种方式写入时,错误显示:如果:

(define (rolling-window l size)
  (if (< (length l) size) l
  (take l size) (rolling-window (cdr l) size)))
(定义(滚动窗口l大小)
(如果(<(长度l)尺寸)l
(采用l尺寸)(滚动窗口(cdr l)尺寸)
当有另一个妄想时,将其分为三个部分:

(define (rolling-window l size)
  (if (< (length l) size) l
  ((take l size) (rolling-window (cdr l) size))))
(定义(滚动窗口l大小)
(如果(<(长度l)尺寸)l
((采用l尺寸)(滚动窗口(cdr l)尺寸)))
然后它说:申请:不是一个程序

如何在racket/scheme中的if's else中编写多个表达式

这不是真正的问题。问题是“如何使用racket构建滚动窗口过程?”。不管怎样,看起来您可能来自另一种编程语言。处理链表一开始可能有点棘手。但是请记住,要计算列表的长度,必须遍历整个列表。因此,在这里使用
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 '())
;; => '()
如何在racket/scheme中的if's else中编写多个表达式

这不是真正的问题。问题是“如何使用racket构建滚动窗口过程?”。不管怎样,看起来您可能来自另一种编程语言。处理链表一开始可能有点棘手。但是请记住,要计算列表的长度,必须遍历整个列表。因此,在这里使用
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 '())
;; => '()

这里有一个替代方案:

#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 !

这里有一个替代方案:

#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 !

以下是OP功能的修改。它包括初始默认为空列表的大纲视图。子列表将添加到此大纲视图,直到
(长度l)
小于
大小

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

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

以下是OP功能的修改。它包括初始默认为空列表的大纲视图。子列表将添加到此大纲视图,直到
(长度l)
小于
大小

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

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

这个有什么改进吗

(define (rolling-window l size)
  (cond ((eq? l '()) '())
        ((< (length l) size) '())
        ((cons (take l size) (rolling-window (cdr l) size)))))
(定义(滚动窗口l大小)
(cond((eq?l’())’())
((<(长度l)尺寸)'))
((cons(采用l尺寸)(滚动窗口(cdr l)尺寸щщ))

这个有什么改进吗

(define (rolling-window l size)
  (cond ((eq? l '()) '())
        ((< (length l) size) '())
        ((cons (take l size) (rolling-window (cdr l) size)))))
(定义(滚动窗口l大小)
(cond((eq?l’())’())
((<(长度l)尺寸)'))
((cons(采用l尺寸)(滚动窗口(cdr l)尺寸щщ))

使用
cond
。或者,使用
begin
let
包裹分支,但使用
cond
可能更容易。(采用l尺寸)(滚动窗口(cdr l)尺寸)应同时位于其他部分,无需第三个alternative@X10Delse部分只能是一个表达式,因此它是
(取l大小)
(滚动窗口(cdr l)大小)
不能在
if
表单中,因为它是第四部分,例如在else部分之后。如果将其包装在
begin
中,则
(取l大小)
将返回一个从未使用过的结果duse
cond
。或者,使用
begin
let
包裹分支,但使用
cond
可能更容易。(采用l尺寸)(滚动窗口(cdr l)尺寸)应同时位于其他部分,无需第三个alternative@X10Delse部分只能是一个表达式,因此它是
(取l大小)
(滚动窗口(cdr l)大小)
不能在
if
表单中,因为它是第四部分,例如在else部分之后。如果您将它包装在
开始
中,那么
(取l大小)
将返回一个从未使用过的结果一个非常好的解决方案。一个小小的注释:由于循环不修改
n
它可以从参数列表中删除。xs的词源是什么?@X10D,
xs
只是
x
的复数。它是多个
x
值的集合-可能在列表、数组、元组等中。这是一个非常好的解决方案。一个小小的注释:由于循环不修改
n
它可以从参数列表中删除。xs的词源是什么?@X10D,
xs
只是
x
的复数。它是多个
x
值的集合-可能在列表、数组、元组等中。1:最好不要进行长度检查。有没有什么方法可以让take函数在列表不够长时自动退出,而不是抛出一个列表太短的错误?2:是的,效率较低,但可读性更高一点?1:最好不要进行长度检查。有没有什么方法可以让take函数在列表不够长时自动退出,而不是抛出一个列表太短的错误?2:是的,效率较低,但可读性更强?