2015-03-19 26 views
2

我有下面的代碼來計算的元素在Haskell的列表中出現:發生次數,並返回最大值序列

data Elem = Vanilla | Choco deriving (Eq,Show) 
maxStarSeq :: [Elem] -> Int 
maxStarSeq [] = 0 
maxStarSeq (Vanilla:xs) = 0 + maxStarSeq xs 
maxStarSeq (Choco:xs) = 1 + maxStarSeq xs 

現在,我怎麼能返回的最大序列元素,而不是絕對計數器?我的意思是,讓我們說,我的名單是:

[Vanilla,Choco,Choco,Vanilla,Choco] 

我的代碼,我會得到3,因爲有在列表3個巧克力字符。我想要的是得到2,因爲這是Choco字符的最大序列,而下一個序列更短。

我需要的是一些方法來比較序列,評估哪些更長,或類似的東西。

回答

5

可以使用worker wrapper模式來達到您想要的結果:

maxStarSeq :: [Elem] -> Int 
maxStarSeq xs = aux xs 0 0 
    where aux [] acc prev = max acc prev 
      aux (Vanilla:xs) acc prev = aux xs (max acc prev) 0 
      aux (Choco:xs) acc prev = aux xs acc (prev + 1) 

prev參數將跟蹤連續Choco參數的當前數目。參數acc的最大參數數量爲Choco。它的價值會在每次遇到Vanilla值時更新。

+0

我想應用此,但是編譯器給我一個錯誤的半最後一排:輸入輔助 – bransharp 2015-03-19 11:21:17

+0

@BranStark最有可能的壓痕解析錯誤問題在你的來源。確保所有的「輔助」都垂直對齊。 – Jubobs 2015-03-19 11:30:56

+0

所有這些都垂直對齊,仍然出現此錯誤。我錯過了什麼? – bransharp 2015-03-20 14:50:20

8

您可以使用groupmaximum

import Data.List 
maxSeqLength :: Eq a => [a] -> Int 
maxSeqLength [] = 0 
maxSeqLength xs = (maximum . map length . group) xs 
+0

謝謝!有沒有另一種方式來做到這一點,只是使用模式匹配? – bransharp 2015-03-19 11:13:55

+2

@BranStark你是什麼意思?該解決方案確實使用模式匹配。 – Jubobs 2015-03-19 11:48:56