4

x(値)とxs(リスト)を取得し、リストからxより大きいすべての値を削除する関数があります。うまくいかないのですが、理由を教えていただけますか?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
4

6 に答える 6

5

正しくないのは次の行だと思います。

(setf xst (remove elem xs))))

の最初の引数setfは場所で、その後に値が続きます。後方にあるように見えます(そして、初期化されていないxstか、初期化されていませんnil)。

これを行う方が簡単かもしれません:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))
于 2008-09-05T18:06:23.810 に答える
4

最も簡潔なAFAIK:

(defun bigger-elements (x xs) (remove x xs :test #'<))

新しいリストを返すと、xs からすべての要素 y が削除されます。

(< y x)

または有名な LOOP を使用します。

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))
于 2008-09-16T14:28:35.957 に答える
1

これをLispWayで実行したい場合は、再帰を使用して新しいリストを返すことができます。

(defun biggerElems (x xs)
  (cond ((null xs) NIL)
        ((< x (car xs))
         (biggerElems x (cdr xs)))
       (t
        (cons (car xs) (biggerElems x (cdr xs))))))

@ルイス・オリヴェイラ

この解決策は、質問に投稿されたものと対比することです。もう少し複雑なことをする必要がある場合は、リストを操作するための再帰的なアプローチに基づいていることが重要です。

于 2008-09-05T18:33:24.057 に答える
1

それは次のように機能しました:

(defun filterBig (x xs)
  (remove-if (lambda (item) (> item x)) xs))

「#」は何のためのものですか? それはそれでコンパイルされませんでした。

于 2008-09-05T18:26:04.167 に答える
1

@Ben: 間違っているのは setf 呼び出しではありません。問題は、彼が xs を更新していないことです。

つまり、要素が削除された状態で xst が xs に設定されていますが、xs は更新されていません。2 番目の要素を削除する場合、xst には最初の要素が含まれます。

xst を xs にバインドし、remove 呼び出しの xs を xst に置き換える必要があります。これにより、x より大きいすべての要素が削除されます。すなわち:

(defun biggerElems(x xs)
  (let ((xst xs))
    (dolist (elem xs)
      (when (> x elem)
        (setf xst (remove elem xst))))
    xst))

xst を (copy-list xs) に設定してから、remove の代わりに delete を使用する方が少し速いかもしれません (delete は破壊的です...実装によっては、remove よりも速い場合があります。これを複数回呼び出しているため、リストを一度コピーして破壊的に削除すると、パフォーマンスが向上する場合があります)。

または:

(defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own
  (loop for elem in xs when (<= x elem) collect elem))

元の投稿を振り返ってみると、少し混乱しています... x より大きいすべての要素を削除すると言いますが、コードは x より大きいすべての要素を削除しようとしているように見えます。私が書いたソリューションは、x より大きいすべての要素を返します (つまり、x がより大きいすべての要素を削除します)。

于 2008-09-22T22:38:47.557 に答える
0

「#」は何のためにありましたか?それはそれでコンパイルされませんでした。

打ち間違え。通常は#'(のような(remove-if #'oddp list))で関数を参照しますが、編集中に「#」を削除するのを忘れました。

于 2008-09-05T18:32:20.907 に答える