2014-01-25 60 views
2

现在我要计算列表中最常见的项目。
我一步一步做到了。计算列表的模式

  1. 排序列表
  2. 组列表
  3. 怎么算每个数字
  4. 我不知道如何继续多次......请帮助。这是我做 代码现在

group     :: Eq a => [a] -> [[a]] 
group     = groupBy (==) 

-- | The 'groupBy' function is the non-overloaded version of 'group'. 
groupBy     :: (a -> a -> Bool) -> [a] -> [[a]] 
groupBy _ []   = [] 
groupBy eq (x:xs)  = (x:ys) : groupBy eq zs 
          where (ys,zs) = span (eq x) xs 


task4 xs = (map (\[email protected](x:xs) -> (x,length l)) (group (sortList xs)))  
<main> task4 [1,1,1,2,2,3] 
     [(1,3),(2,2),(3,1)] 
+0

你知道这不是一个有效的方法吗?快速方法是保持值到计数器的映射。对于每个值,然后查找并递增每个计数器值。粗糙的,这需要一个Hashable,Ord或其他一些辅助约束。 –

+0

@ ThomasM.DuBuisson效率不高?它是O(n log n)时间(排序步骤;之后的所有内容都是线性时间)。 – delnan

+0

你认为这种行为是不是? –

回答

2

你非常接近。如果不是:

(\[email protected](x:xs) -> (x,length l)) 

你写道:

(\[email protected](x:xs) -> (length l,x)) 

,那么你可以简单地把你的输出maximum

maximum [(3,1),(2,2),(1,3)] == (3,1) 
+0

啊...是的。你是对的。这是关于思考。非常感谢你 – Xie

4

让我们先假设你只有在多久感兴趣该模式变成。所以你只需使用

map length . group $ sortList xs 

给你一个单个组的长度列表。然后剩下要做的就是检索maximum

现在,这不是你想要的。基本上,你想要最大的元组列表,但它只应该比较长度字段,而不是元素一。您可能会因此受到注意hoogle for Ord b => [(a, b)] -> a(或-> (a,b)),但没有这样的标准功能。

但是,因为您已经搜索了最大值,并且这种特殊形式正是您想要的,所以您可以向下滚动该结果页面,您会发现maximumBy。它允许您指定应考虑哪些“属性”进行比较。

使用此的优选方式是相当不言自明的

GHCI>:M + Data.Ord Data.List模块
GHCI>:吨maximumBy(比较SND)
maximumBy(比较SND )::奥德A => [(A1,A)] - >(A1,A)

因此,我们正在处理的如何访问关键领域作为参数传递给函数的信息。那么,但作为snd本身就是一个功能,我们还可以使用任何其他的!因此,有没有真正的需要建立起来的ELEM +游程的元组在首位,你可能也只是做

 maximumBy (comparing length) . group $ sort xs 

这给正确的结果(虽然这是一个有点低效率)。总之:

mode :: Ord a => [a] -> a 
mode = maximumBy (comparing length) . group . sort