我正在嘗試撰寫一個函式,該函式回傳串列中出現次數最多的元素。到目前為止,我有以下內容
task :: Eq a => [a] -> a
task xs = (map ((\l@(x:xs) -> (x,length l)) (occur (sort xs))))
occur是一個函式,它接受一個串列并回傳一個對串列,其中包含輸入串列的元素以及它們出現的次數。因此,例如對于串列[1,1,2,3,3],輸出將是[(1,2),(2,1),(3,2)].
但是,我收到了一些與map. 誰能告訴我我做錯了什么?
uj5u.com熱心網友回復:
映射將每個專案映射到另一個專案,因此這里\l是一個 2 元組,例如(1,2),(2, 1)或(3, 2)。因此,使用 沒有多大意義length l,因為length :: Foldable f => f a -> Int對于 2 元組總是回傳一個:這是因為在可折疊中只使用了 2 元組的第二部分。但是我們一開始就不需要length。
您需要的是一個可以根據 2 元組的第二項檢索最大值的函式。我們可以使用maximumOn :: Ord b => (a -> b) -> [a] -> a來自exta包的,或者我們可以實作我們自己的函式來計算專案串列的最大值。
因此,這樣的函式應該如下所示:
maximumSnd :: Ord b => [(a, b)] -> (a, b)
maximumSnd [] = error "Empty list"
maximumSnd (x:xs) = go xs x
where go [] m = m
go (x@(xa, xb):xs) (ya, yb)
| xb > yb = go … … -- (1)
| otherwise = go … … -- (2)
這里 (1) 應該被實作,以便我們進行遞回呼叫,但使用x我們迄今為止發現的新最大值。(2)應該與遞回呼叫相同迄今為止最大。
一旦我們實作了這個maxSnd函式,我們就可以使用這個函式作為一個輔助函式:
task :: Eq a => [a] -> (a, Int)
task xs = maxSnd (occur xs)
或者我們可以fst :: (a, b) -> a用來檢索 2 元組的第一項:
task :: Eq a => [a] -> a
task xs = (fst . maxSnd) (occur xs)
如果有兩個字符具有最大元素數,maximumSnd則將回傳出現串列中的第一個。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316824.html
