方案:从列表前面到后面的所有可能的移位

时间:2012-02-16 06:43:34

标签: scheme racket

我需要编写一个Scheme函数,该函数将列表作为参数,并返回列表列表,其中每个列表都是原始列表的循环。 一个循环,我的意思是将第一个元素移动到最后一个位置。 我有以下功能:

(define (cycle lst)
  (cond ((null? lst) '())
        ((null? (cdr lst)) lst)
        (else (append (cdr lst) (list (car lst)))))) 

(define (shift lst)
  (define (iter l cycles result)
    (cond ((= cycles 0) (cons lst result))
          ((< cycles 1) result)
          (else (iter (cycle-1 l) (- cycles 1) (cons result (cycle-1 l))))))
  (iter lst (- (length lst) 1) '()))

现在,当我这样做时: (班次'(1 2 3)) 我明白了: '((1 2 3)(()2 3 1)3 1 2) 我应该得到: '((1 2 3)(2 3 1)(3 1 2))

1 个答案:

答案 0 :(得分:1)

(define (shift lst)
  (define (iter l cycles result)
    (cond ((= cycles 0)
           (cons lst result))
          ((< cycles 0) result)
          (else (let ((cycled (cycle l)))
                  (iter cycled (- cycles 1) (cons cycled result))))))
  (iter lst (- (length lst) 1) '()))

首先,我做了一个简单的改进,以防止计算列表的循环形式两次(添加let)。其次,您需要cycledresult,因为您需要附加result列表,而不是cycled列表。在您的代码中,您将最后结果添加到旧结果中,然后将此错误添加的结果列表作为iter参数传递给result函数。

更新:要在您的订单中获得结果,您可以简单地使用循环列表附加结果,而不是将循环列表添加到结果的开头:

(define (shift lst)
  (define (iter l cycles result)
    (cond ((= cycles 0)
           (cons lst result))
          ((< cycles 0) result)
          (else (let ((cycled (cycle l)))
                  (iter cycled (- cycles 1) (append result (list cycled)))))))
  (iter lst (- (length lst) 1) '()))