2010-12-03 3 views
1

から重複を削除します。ここでは、私がデータ型を持っているリスト

*Main> let a = [Sides 3 4 5,Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25] 
*Main> removeDuplicateFromList [] a 
[Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25] 

は私のソリューションです:より多くのHaskellの-方法でこのコードを記述する他の方法があるかどう

removeElementFromList :: [SidesType] -> SidesType -> [SidesType] 
removeElementFromList lst element = 
         let (Sides a b c) = element 
         in [(Sides x y z) | (Sides x y z) <- lst, (x /= a) || (y /= b)] 

removeDuplicateFromList :: [SidesType] -> [SidesType] -> [SidesType] 
removeDuplicateFromList inlist outlist 
         | (length outlist) == 0 = inlist 
         | otherwise = 
          let element = head outlist 
           b = tail outlist 
           filtered = removeElementFromList b element 
         in removeDuplicateFromList (inlist ++ [element]) filtered 

は、私は疑問に思って?それはO(N^2)

+2

'(長出力リスト)の検索ウィキペディア== 0 ' - >'ヌルoutlist' –

答えて

6

あなたのデータ型にはShowが派生しています。 Eqも派生している場合は、nubmodule Data.Listから使用できます。

0

使用Data.List.nub

+0

私が使用する方法を見つけることはありませんそれはカスタムデータ型です。そして、タイプの3つのメンバーのうち2つだけをチェックします:(x/= a)|| (y =/b) – demas

+1

次にnubBy ::(a - > a - >ブール) - > [a] - > [a] –

+0

またはnewtypeでラップしてください! NubByを使うよりもはるかにエレガントです;) –

2

ですがあなたは既にしている

nubBy :: (a -> a -> Bool) -> [a] -> [a] 

PS:柔軟性を追加機能 "により、" そこにあるいつものように

0

まずも注文クラスを派生:

data XYZ = XYZ .... deriving (Show, Eq, Ord) 

または式インスタンス上であなたを書く:

instance Eq XYZ where 
a == b = ... 

その後インテリジェントこととツリーを使用します! [コンピュータサイエンス木は上から下へと成長!] [1]、長さNとのリストについては、(右から左へ)

import qualified Data.Map.Strict as Map 

removeDuplicates ::[a] -> [a] 
removeDuplicates list = map fst $ Map.toList $ Map.fromList $ map (\a -> (a,a)) list 

複雑さ:

  1. リストのマップ:O(N)
  2. Map.fromList:O(N * Nログ)
  3. Map.toList:より小さいまたはNに等しいリストの長さを持つリスト上のO(Nログ)
  4. マップ:O(N)

それらが連続と呼ばれ、これは、部品の複雑さとの間のプラスがある=> O(2 * N + N * Nのログ+ Nログ)= O(N * Nログ)

これはリストよりN^2回横断するよりも良い方法です! 参照:wolframAlpha plots比較のために2 * Nも含めました。

2 + 3:http://hackage.haskell.org/package/containers-0.5.4.0/docs/Data-Map-Strict.html

[1]:コンピュータサイエンスツリー

+0

私はこのアルゴリズムを高速化するために、 'XYZ'や' Ord'インスタンスのような型を与えるのをためらっています。このようなインスタンスも概念的に意味をなさないはずです!リストにとどまり、 'map head 'を使うことで同じ複雑さを達成することができます。グループ。 'nub'の代わりに' sortBy adHocOrd'を使用し、提案されたOrd'インスタンスの "インライン定義"を使用します。あるいは、あなたが本当にパフォーマンスを気にしているならば、代わりに 'Hashable'インスタンスを定義してください:ハッシュマップで、これを_O_(_n_)にすることができます! – leftaroundabout

+0

まあ、ハッシュテーブルはもちろん意味があります。私は以前にそのパッケージについて知りませんでした...(まあ、実際には、配列などで必要とされるプリミティブパッケージについてはわかりませんでした)。 しかし、Ordインスタンスは何が悪いですか?少なくとも部分的な順序付けが定義されている型であれば、それは問題ではありません。または私は間違っていますか? Btw:返信いただきありがとうございます。 – Schnecki

+0

部分的な順序付けを定義することができますが、_canonical_を定義することはできませんが、数学的に明白な解釈があるという意味でかなりの種類があります。典型的な例は[複素数](http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Complex.html#t:Complex)だけでなく、ベクトル型任意の「Ord」インスタンスは、いくつかの特定の根拠を利用する必要がありますが、妥当性がある複数の異なるインスタンスが存在することがよくあります)。そしてOPが本当にベクタのように見えます。 – leftaroundabout

関連する問題