6

Common Lisp で最後の要素のないリストを返すばかげた関数を書きました。この問題に対するよりエレガントな解決策はありますか?

これが私のコードです:

(defun list-without-last (l)
  (if (> (length (rest l)) 0)
      (append (list (first l)) (list-without-last (rest l)))
      nil))
4

6 に答える 6

13

Lisp のように、短くてシンプルです。ここに魔法のものがあります:

(defun without-last(l) (reverse (cdr (reverse l))) )

于 2014-04-09T21:58:18.717 に答える
9

関数には 2 つの問題があります。

  • あなたはLENGTHを使用しています。LENGTH はリスト全体をスキャンする必要があります。

  • APPEND を使用しています。CONSを使用してみてください。短所はより簡単です。

Common Lisp もすでにこの機能を提供しています。それはBUTLASTと呼ばれています。

実際のコードでは、再帰も使用しません。スタック サイズによって、処理できるリストの長さが制限されます。

LOOPマクロを使用した反復バージョン:

CL-USER> (defun my-butlast (list)
           (loop for l on list
                 while (rest l)
                 collect (first l)))
MY-BUTLAST                                                                                                                                      
CL-USER> (compile 'my-butlast)
MY-BUTLAST                                                                                                                                      
NIL                                                                                                                                             
NIL                                                                                                                                             
CL-USER> (my-butlast '(1 2 3 4 5))
(1 2 3 4)                                                                                                                                       
CL-USER> (my-butlast '(1))
NIL                                                                                                                                             
CL-USER> (my-butlast '(1 2))
(1)                                                                                                                                             
于 2012-05-17T13:26:03.597 に答える
2

コピーを作成するのではなく、その場でリストを変更する必要がある場合があります。その場合、これが便利な場合があります。

(defun butlast! (x)
  (do ((y x (cdr y)))
      ((null (cddr y))
       (and (rplacd y nil) (return x)))))
于 2012-05-18T20:19:39.157 に答える