2017-04-16 43 views
0

所以我試圖遞歸地實現LISP中的一個凱撒密碼,並且我已經獲得了基本的功能性工作。問題是它返回一個字符列表,並且在返回語句中調用串聯'字符串只是返回相同的字符列表加上一個「」。我在這裏做錯了什麼?遞歸共同的字符串列表LISP

(defun caesar (s n) 
    (if (null (concatenate 'list s)) 
     '() 
     (cons 
      (code-char (+ n (char-code (car (concatenate 'list s))))) 
      (caesar (coerce (cdr (concatenate 'list s)) 'string) n) 
     ) 
    ) 
) 
+0

你的一半程序似乎丟失:specificallt'stringtolist' – tfb

+0

糟糕,提供了舊代碼,更新了 –

+0

沒有任何格式,你的代碼是不可讀的。你可能想要格式化你的代碼。預計你會在你的問題上付出最少的努力。 –

回答

2

的正確方法是這樣是做字符串&列表之間的轉換,在某種&的包裝則有名單上的主要功能工作。

這是一種使用CL的一些力量和優雅的方法。這:

  • 採用CLOS方法來做包裝 - 這將可能使其沒有資格提交家庭作業,因爲是它是什麼情況,不過是CLOS多漂亮可我覺得一個良好的示範,並也是我如何寫這樣的東西;
  • 在包裝方法中使用coerce而不是concatenate來更改類型,因爲這就是它的用途;
  • 故意做不是處理一些圍繞遞歸原始代碼的其他問題& char-codes。

的一切都在這裏首先是使用兩種方法的一個版本:該做的工作的包裝方法(爲方便起見通用函數定義中定義),然後遞歸方法:

(defgeneric caesar (text n) 
    (:method ((text string) n) 
    ;; if we're given a string just turn it into a list, then recurse 
    ;; on the list & turn it back to a string (of the same type, hence 
    ;; TYPE-OF). 
    (coerce (caesar (coerce text 'list) n) (type-of text)))) 

(defmethod caesar ((text list) n) 
    ;; The recursive level (note this has various issues which are in 
    ;; the original code & not addressed here 
    (if (null text) 
     '() 
    (cons (code-char (+ n (char-code (first text)))) 
      (caesar (rest text) n)))) 

其次這裏是一種稍微太聰明的方法,採用特殊的終止方式。我不會推薦這個,但它是CLOS可以做的事情的一個簡單演示。

(defgeneric caesar (text n) 
    (:method ((text string) n) 
    ;; if we're given a string just turn it into a list, then recurse 
    ;; on the list & turn it back to a string (of the same type, hence 
    ;; TYPE-OF). 
    (coerce (caesar (coerce text 'list) n) (type-of text)))) 

(defmethod caesar ((text null) n) 
    ;; termination 
    '()) 

(defmethod caesar ((text list) n) 
    ;; The recursive level (note this has various issues which are in 
    ;; the original code & not addressed here 
    (cons (code-char (+ n (char-code (first text)))) 
     (caesar (rest text) n))) 
0

我會被誘惑結合起來輸出到字符串和標籤(用於遞歸位):

(defun caesar (s n) 
    (with-output-to-string (cipher) 
    (labels ((beef (s) 
       (when s 
        (princ <whatever> cipher) 
        (beef (rest s))))) 
     (beef (coerce s 'list))))) 

警告:上面是徹底未經測試,簡單地輸入到該消息,所以很可能甚至不會編譯。它只是使建議更具針對性。