2015-07-02 27 views
4

我想做两个整数列表之间的差异,它允许haskell重复。Haskell中的列表中有Ord运算符吗?

所以在有[1,2,1,4,3] [1,2,4]的情况下,所不同的是[1,3]

目前我可以通过正常\\操作listA \\ listB做到这一点。

但问题是这太慢了。由于整数是在组中,它可以更快地完成。

我知道Data.Multiset模块,它会做得更快,但有一种本地方式可以在没有Data.Multiset模块的列表上执行它吗?

+0

也许你应该考虑Data.IntSet。 – augustss

+1

Set结构的问题是它不包含重复计数。例如,如果我们在第一个列表中有4个,并且在第二个列表中。设置的差异将是[1],因为第一个列表中的数量多于第一个列表中的数量。 – Aleksandar

+1

出于某种原因,您似乎反对使用库代码,但[Data.List.Ordered](http://hackage.haskell.org/package/data-ordlist-0.4.7.0/docs/Data-List-Ordered .html)对已排序的列表进行了类似set和bag的操作,包括[minus](http://hackage.haskell.org/package/data-ordlist-0.4.7.0/docs/Data-List-Ordered.html#五:负)。 –

回答

6

由于整数在ord组中,它可以做得更快。

是的,但它需要建立一个排序索引。这几乎是Data.Multiset正在做的事情。你当然可以编写一个手动执行的操作,但到那时你将有效地重新实现Multiset

1

因为我不能使用Data.MultiSet我需要通过列表来实现我自己的解决方案,所以我会发布解决方案。

为了得到两份名单与repetitons差集,我们首先需要组数字相加,得到每个号码的重复量:

tupleGroup [] _ = [] 
tupleGroup (hd:tl) (x, y) 
    | hd == x = (x, succ y) : tupleGroup tl (x, succ y) 
    | otherwise = (hd, 1) : tupleGroup tl (hd, 1) 

group' [] = [] 
group' (hd:tl) = tupleGroup tl (hd, 1) 

为了调用辅助函数组',我们首先需要对列表进行排序,因为tupleGroup需要一个排序列表。

下一页功能是区别功能,在我们提供的分组列表:

difference [] [] = [] 
difference (hd:tl) [] = fst hd : difference tl [] 
difference [] (hd:tl) = [] 
difference (hd1:tl1) (hd2:tl2) 
    | x1 == x2 && y1 > y2 = x1 : difference tl1 tl2 
    | x1 == x2 = difference tl1 tl2 
    | x1 < x2 = x1 : difference tl1 (hd2:tl2) 
    | otherwise = difference (hd1:tl1) tl2 
    where 
    x1 = fst hd1 
    x2 = fst hd2 
    y1 = snd hd1 
    y2 = snd hd2 

该函数将返回所有号码的列表,其中重复计数是在第一个列表更大,比第二个。