2014-01-25 59 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