2011-02-08 34 views
1

2つのリストを比較して同じセットを表すかどうかを調べる関数を作成しようとしています。つまり、'(a b c d d)'(d c b a d)は同じセットを表します。要素は任意の順序で指定できます。セットを比較する関数。

これは働く、私が持っているものです。

(defun samesetp (list1 list2) 
    (cond 
    ((null list1) (null list2)) 
    ((eq list2 (remove (car list1) list2 :count 1)) nil) 
    (t (samesetP (cdr list1) (remove (car list1) list2 :count 1)))))) 

私は、これは(remove (car list1) list2 :count 1))は二回に計算されていることである好きではない理由 - remove操作は、本当に何かを取り除くかどうかをテストするために、一度、一度再帰的にそのリストの残りの部分をテストしてその要素を削除します。

誰かが別のアルゴリズムを使用せずにこれを改善する方法を提案できますか?

+1

あなたはハッシュテーブルを使用する必要があり、これはOから複雑さをダウンさせるだろう^ 2)をO(n)に変換する。 – leppie

+1

私は混乱しています。あなたはひどいアルゴリズムを使用しており、不正なアルゴリズムを修正する必要がない限り改善が望まれます。どうして? @leppieは言ったように、ハッシュテーブルを使用します。あるいは、両方のリストを並べ替えて並行して歩くこともできます。より良いアルゴリズムは、あなたが関心を持つマイクロ最適化よりもはるかに大きな違いを生み出します。 – btilly

+0

寒い人は、私たちはハッシュテーブルを使用することはできません。宿題の問題の一部です。コードの約10行以内に含まれるより効率的なアルゴリズムについて考えることができるなら、私に教えてください。 –

答えて

10
(defun samesetp (list1 list2) 
    (cond 
     ((null list1) (null list2)) 
     ((eq list2 (remove (car list1) list2 :count 1)) nil) 
     (t (samesetP (cdr list1) (remove (car list1) list2 :count 1)))) 
    ) 
) 

まずはそれを正しくフォーマットしてみましょう:

(defun samesetp (list1 list2) 
    (cond ((null list1) (null list2)) 
     ((eq list2 (remove (car list1) list2 :count 1)) nil) 
     (t (samesetP (cdr list1) (remove (car list1) list2 :count 1))))) 

あなたは二度のフォームを使用していて、それを変更したい場合は、あなたが値を格納する必要があります。 LETはそのための構成です。 1つのCONDに収まらない場合は、2つ目のCONDが必要です。

(defun samesetp (list1 list2) 
    (cond ((null list1) (null list2)) 
     (t (let ((list3 (remove (car list1) list2 :count 1))) 
      (cond ((eq list2 list3) nil) 
        (t (samesetP (cdr list1) list3))))))) 

ここで、EQを使用してリストを比較することはできません。等号を使用してください。

(defun samesetp (list1 list2) 
    (cond ((null list1) (null list2)) 
     (t (let ((list3 (remove (car list1) list2 :count 1))) 
      (cond ((equal list2 list3) nil) 
        (t (samesetP (cdr list1) list3))))))) 

CONDは場合に使用します、ここで過剰です:

(defun samesetp (list1 list2) 
    (if (null list1) 
     (null list2) 
    (let ((list3 (remove (car list1) list2 :count 1))) 
     (if (equal list2 list3) 
      nil 
     (samesetP (cdr list1) list3))))) 

今、あなただけの機能が宿題に頼まれたものを行うようにする必要があります。とにかくあなたの宿題です。

+0

ありがとうございます。私は本当にここで助けてくれるものがあると思う。 –

+1

これがあなたを助けてくれた場合は、Rainerの回答を合格とマークする必要があります。私はそれが良い答えだと付け加えます。だから+1。 – Shaun

+1

はい、私はそれに印をつけました。ありがとうライナー私は本当に助けに感謝しています! –

1

私はあなたが1がある問題を解決するための組み込み関数を使用することはできませんが、ちょうど注意することが推測:N(

(set-difference list1 list2) 
+1

ITYM 'set-exclusive-or'です。 'set-difference'では、引数の順序が重要です。 –

関連する問題