3

我对方案很陌生,我想获取一个诸如 (1 2 3 4) 之类的列表并将其发送到将返回 (4 1 2 3) 的函数。第二次运行将返回 (3 4 1 2),依此类推,每次调用该函数时都会创建一个右移列表。

我想出解决这个问题的第一种方法是递归地交换列表的第一个和最后一个值。因此,在方案中,我会将列表的 car 附加到列表的 cdr 并递归地将列表的 cdr 发送回我的函数,直到只能进行最后一次交换。

但是,我不擅长创建递归函数,而且我在使用新语言(例如方案)时遇到了麻烦。到目前为止,这就是我试图给出的关于我想去哪里的想法。

(define (rShift lst)
  (if (null? lst)
      '()
      (append (cdr lst (car lst))(rShift (cdr lst)))))
4

2 回答 2

0

如果您打算执行递归解决方案,那么您需要问自己“问题的哪一部分可以解决,留下相同但较小的问题部分”以及“我如何结束递归”。

对于您的问题,当您拥有最后一个元素时结束递归,然后您可以使用该元素添加到列表的前面。问题是使用“右移”进行递归是不够的,因为您需要保留列表才能将最后一个元素放在其前面。

所以:

(define (right-shift list)
  (if (null? list)
      '()
      (let shifting ((list list) (result '()))
        (if (null? (cdr list))
            (cons (car list) (reverse result))
            (shifting (cdr list) (cons (car list) result))))))
;; Hey look, it compiles... gosh I love interactive languages.

;; ... and works.
> (right-shift '(1 2 3 4))
(4 1 2 3)
> (right-shift (right-shift '(1 2 3 4)))
(3 4 1 2)
于 2013-06-23T01:11:10.773 回答
0

您可以做的最好的事情是查看解释器的文档以查看可用的列表函数,并使用它们构建解决方案。例如,在 Racket 中使用列表程序将完成一个简单的解决方案:

(define (rShift lst)
  (cons                             ; stick together the solution
   (last lst)                       ; pick the last item
   (take lst (sub1 (length lst))))) ; pick all items except the last one

试一试吧:

(rShift '(1 2 3 4))
=> '(4 1 2 3)

(rShift (rShift '(1 2 3 4)))
=> '(3 4 1 2)

有无数种方法可以解决这个问题,我会让你找到最适合你需求的方法,但请记住 - 始终尝试根据你已经掌握的构建块来解决问题,不要重新发明轮子。只是为了好玩,这是另一种方式,使用reverse

(define (rShift lst)
  (let ((rev (reverse lst)))
    (cons (car rev)
          (reverse (cdr rev)))))
于 2013-06-22T22:49:04.487 回答