Scheme 向左移动k次
嗨,我正在尝试在scheme中实现一个程序,将列表向左移动k次。 例如:Scheme 向左移动k次,scheme,racket,Scheme,Racket,嗨,我正在尝试在scheme中实现一个程序,将列表向左移动k次。 例如: (shift-k-left ’(1 2 3) 2) ’(3 1 2) 我成功地实现了一个代码,在这里左移一次: (define shift-left (lambda (ls) (if (null? ls) '() (append (cdr ls) (cons (car ls) '()))))) 我想在shift-k-left上使用shift
(shift-k-left ’(1 2 3) 2)
’(3 1 2)
我成功地实现了一个代码,在这里左移一次:
(define shift-left
(lambda (ls)
(if (null? ls)
'()
(append (cdr ls)
(cons (car ls)
'())))))
我想在shift-k-left上使用shift left作为函数。这里有一些类似的功能:
(define (addn value n)
(let loop ((value value) (n n))
(if (zero? n)
value
(loop (add1 value) (- n 1)))))
(addn 5 3)
; ==> 8
现在你可以做一个抽象:
(define (repeat proc)
(lambda (v n)
...))
(define addn (repeat add1))
(addn 5 3)
; ==> 8
(define shift-k-left (repeat shift-left))
(shift-k-left ’(1 2 3) 2)
; ==> (3 1 2)
不用说,repeat
看起来与add1
非常相似
注:命名已关闭。您的实现更像是“旋转”而不是“移位”。
左移
实际上更像是cdr
,而不是你的实现。的想法是倒计时n
,而cons
将r
的汽车
倒推到p
和cdr
s倒推到r
的后面。如果我们遇到一个null?
r
我们反转p
并继续旋转:
(define (shift-k-left l n)
; assume that n >= 0
(let loop ((n n) (p '()) (r l))
(if (= n 0)
(append r (reverse p))
(if (null? r)
(loop n '() (reverse p))
(loop (- n 1) (cons (car r) p) (cdr r))))))
下面是使用srfi/1中的循环列表的解决方案
(require srfi/1)
(define (shift xs k)
(define n (length xs))
(take (drop (apply circular-list xs) k) n))
使用左移
来移动k
次:
- 如果
k
为0:不执行任何操作
- 如果
k
不是0:shiftk-1
次,然后shift left
结果
就是
(define (shift-left-k ls k)
(if (= k 0)
ls
(shift-left (shift-left-k ls (- k 1)))))
您可能需要调整以对负k
执行一些合理的操作