2013-06-22 40 views
2

我對方案很陌生,我想將列表(例如(1 2 3 4))發送給一個將返回的函數(4 1 2 3)。第二次運行將返回(3 4 1 2)等等,每次調用該函數時創建一個右移列表。將列表的第一個元素遞歸追加到列表的其餘部分

我想出解決這個問題的第一種方法是遞歸交換列表的第一個和最後一個值。因此,在方案中,我會將列表的汽車追加到列表的cdr中,並遞歸地將列表的cdr發送回我的函數,直到只有最後一次交換爲止。

但是,我不擅長創建遞歸函數,而且我很難用一種新語言來完成,比如計劃。這是我迄今爲止試圖給出我想要去哪裏的想法。

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

你沒有測試的代碼。那'(cdr lst(car lst))'部分甚至不會編譯。 –

回答

0

您可以做的最好的方法是查看解釋器的文檔,查看可用的列表函數,並使用它們構造解決方案。例如,在球拍使用list procedures將實現一個簡單的解決方案:

(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))))) 
+0

謝謝,因爲我已經瞭解了更多已經內置的功能方案,所以它變得更加容易。 – Yoink

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) 
+0

在單名空間域中調用參數*列表*不是一個好習慣。 – uselpa

+0

或者它是計劃之美的一部分。當我們理解詞彙環境時;一個人理解一切。 – GoZoner

相關問題