web-dev-qa-db-ja.com

LISPのリストの最後に追加する

重複の可能性:
リストの最後にアイテムを追加するための「短所」とは何ですか?

LISPで多くのチュートリアルを見て、グーグルで答えを高低で検索した後でも、LISPのリストの最後に追加する方法がわかりません。

関数にリストの最後に_'a_を追加したいのですが'(b c d)ですが、前に追加する方法しかわかりません。誰かが私が短所を正しく使用してリストの最後に_'a_を追加するのを手伝ってもらえますか?これが私のコードです。前もって感謝します。

_(defun AddRt (a list)
  (cond
    ((null list)
      0)
    (t
      (princ (cons a (cons (car list) (cdr list))))
    )))


(AddRt 'a '(b c d))
_
13
Bert

Push から last 、または nconc を使用します。

_> (defparameter a (list 1 2 3))
A
> (Push 4 (cdr (last a)))
(4)
> a
(1 2 3 4)
> (nconc a (list 5))
(1 2 3 4 5)
> a
(1 2 3 4 5)
_

これらは destructiveoperators であることに注意してください。つまり、値であるオブジェクトを変更します。 aだけでなく、abinding

そのため、ところで、_(nconc '(1 2 3) '(4 5 6))_のように、引用符で囲まれたリストでは絶対にnconcを使用しないでください。

PS。リストのendに追加するには、fullトラバーサルが必要であるため、O(length(list))操作であることに注意してください。リストが長い場合、これは悪い考えかもしれません。そのため、人々はしばしば Push / nreverse イディオムを使用します。

_(let (range)
  (dotimes (i 10 (nreverse range))
    (Push i range)))
==> (0 1 2 3 4 5 6 7 8 9)
_
18
sds

再帰関数を使用できます。また、内部でprincを使用することは避けてください。

次の関数endconsは、consとまったく同じことを行います。ただし、値は最後に追加されます。

(defun endcons (a v)
   (if (null v) (cons a nil) (cons (car v) (endcons a (cdr v)))))

(endcons 'a '(b c d))

もちろん、appendを使用することもできます:

(append '(b c d) '(a))

この関連する質問も参照してください: リストの最後にアイテムを追加するための「短所」とは何ですか?

6
user1220978

1つの方法は、リストを逆にすることです。反転リストの先頭に要素を追加します。そして最後にリスト全体を逆にします。

スキームコード:

(define (add-to-tail l x)
   (reverse (cons x (reverse l)))

ただし、これが頻繁に必要な操作である場合は、(単一リンク)リスト以外のデータ構造を見つけることをお勧めします。

4
soegaard