2017-04-16 8 views
0

私はLISPでCaesar暗号を再帰的に実装しようとしています。基本的な機能が動作しています。問題は文字のリストを返すことで、return文でconcatenate 'stringを呼び出すと、同じ文字列に ""を加えたものだけが返されます。私はここで間違って何をしていますか?共通の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は私が考えることができるか、かなりの良いデモであ​​る場合には、これはおそらく宿題として提出するためには不適格になりますし、私は実際にこのようなものをどのように書くのかです。
  • はタイプを変更するためにconcatenateではなくラッパーメソッドでcoerceを使用します。
  • 意図的にではないは、再帰&の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)))) 
    

    :(便宜上一般的な関数定義で定義された)ラッパー・メソッドと、その後の作業を行い、再帰的方法:

まず第一には、ここでは2つのメソッドを使用するバージョンであります特別な終了時の-nullメソッドを使用して、やや賢明なアプローチです。私はこれをお勧めしませんが、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))))) 

警告:上記は徹底的にテストされていないと、単にこのメッセージに入力し、コンパイルされない可能性もあります。それは単に提案をもっとcncreteにします。

関連する問題