1

私はこのような関数で比較をしようとしています:

(defun omember (x l)
  (cond
    ((null l) nil)
    ((eq (car l) x) t)
    ((string< (car l) x) (omember (x (cdr l))))
    (t nil)))

リストを調べて、リストlの要素にxがあるかどうかを検索するだけです。渡されたリストはソートされているため、すべてのリストで値を検索する必要はありません。値が要素より大きい限り、nil を返すことができます。ただし、「未満」機能は機能しません。文字列と整数に対して「string<」と「<」を試しました。また、渡されたリストは整数または文字列のいずれかである可能性があるため、リスト内の整数を文字列にして文字列で比較するメカニズムがあるかどうか疑問に思っています。

4

4 に答える 4

1

これを一般的な方法で機能させたい場合は、比較関数をパラメーターとして渡す必要があります。

(defun member-of-sorted (item list
                         &key (test #'=) (end-test #'<) (key #'identity))
  (loop :for tail :on list
        :for element := (funcall key (first tail))
        :until (funcall end-test item element)
        :when (funcall test item element)
        :do (return-from member-of-sorted tail))
  nil)

これをできるだけ標準に近づけようとしましたmember。数値ではなく他のものに使用したい場合は、適切なパラメータ:test:end-testパラメータを渡します。同じ使用場所に異なるタイプがある場合は、これをタイプケース フォームでラップできます。

編集:使用例を追加する必要があります:

(member-of-sorted 3 '(1 2 3 4 5 6))
=> (3 4 5 6)

(member-of-sorted 3/2 '(1 2 3 4 5 6))
=> NIL

(member-of-sorted "foo" '("bar" "baz" "foo" "quux")
                  :test #'string=
                  :end-test #'string<)
=> ("foo" "quux")

(member-of-sorted #\D '(#\A #\C #\E #\S)
                  :test #'char=
                  :end-test #'char<)
=> NIL

(member-of-sorted #\D '(#\A #\C #\D #\E #\S)
                  :test #'char=
                  :end-test #'char<)
=> (#\D #\E #\S)
于 2012-11-03T11:32:59.523 に答える
0

再帰omemberの前後に括弧を使用するとエラーが発生します。

(defun omember(x l)
  (cond
    ((null l) nil)
    ((= (car l) x) t)
    ((< (car l) x) (omember x (cdr l)))
    (t nil)
    )
  )

整数のリストに対してこれが機能するようになります

(defun omember(x l)
      (cond
        ((null l) nil)
        ((string= (car l) x) t)
        ((string< (car l) x) (omember x (cdr l)))
        (t nil)
        )
      )

文字列のリストで機能するようになります

しかし、文字列のリストと整数のリストの両方で機能するようにする方法はないようです

于 2012-11-02T21:03:22.983 に答える
0

タイプを区別するには、コードで次を使用します。

[15]> (typep 7 'integer)
T
[16]> (typep "17" 'string)
T
于 2012-11-02T09:17:31.907 に答える
0

applyを使用して、関数オブジェクトを引数のリストに適用できます。

((apply *lessthan* (list (car l) x)) (do something))

またはfuncall wvxvw が指摘するように、追加のリストを作成する必要はありません:

((funcall *lessthan* (car l) x) (do something))
于 2012-11-02T08:14:54.447 に答える