2017-04-16 46 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))))) 

警告:上面是彻底未经测试,简单地输入到该消息,所以很可能甚至不会编译。它只是使建议更具针对性。