如何获取列表示例中最常用的值:
[1,3,4,5,6,6] -> output 6
[1,3,1,5] -> output 1我正在尝试通过我自己的函数来获得它,但我无法实现它,你们能帮助我吗?
我的代码:
del x [] = []
del x (y:ys) = if x /= y
then y:del x y
else del x ys
obj x []= []
obj x (y:ys) = if x== y then y:obj x y else(obj x ys)
tam [] = 0
tam (x:y) = 1+tam y
fun (n1:[]) (n:[]) [] =n1
fun (n1:[]) (n:[]) (x:s) =if (tam(obj x (x:s)))>n then fun (x:[]) ((tam(obj x (x:s))):[]) (del x (x:s)) else(fun (n1:[]) (n:[]) (del x (x:s)))
rep (x:s) = fun (x:[]) ((tam(obj x (x:s))):[]) (del x (x:s))发布于 2012-12-12 19:44:25
根据萨特维克的最后一个建议,您可以使用Control.Arrow中的(&&&) :: (b -> c) -> (b -> c') -> (b -> (c, c')) (注意,为简单起见,我在该类型签名中替换了a = (->) )来干净利落地执行decorate-sort-undecorate transform。
mostCommon list = fst . maximumBy (compare `on` snd) $ elemCount
where elemCount = map (head &&& length) . group . sort $ listhead &&& length函数的类型为[b] -> (b, Int)。它将列表转换为第一个元素及其长度的元组,因此当它与group . sort组合时,您将获得列表中每个不同值的列表以及它出现的次数。
此外,您还应该考虑调用mostCommon []时会发生什么。显然没有合理的值,因为根本没有元素。就目前而言,所有提出的解决方案(包括我的)都会在一个空列表上失败,这不是一个好的Haskell。通常的做法是返回一个Maybe a,其中Nothing表示一个错误(在本例中是一个空列表),Just a表示一个“真正的”返回值。例如:
mostCommon :: Ord a => [a] -> Maybe a
mostCommon [] = Nothing
mostCommon list = Just ... -- your implementation here这要好得多,因为从代码安全的角度来看,部分函数(对于某些输入值未定义的函数)是可怕的。您可以使用模式匹配(在Nothing和Just x上匹配)和Data.Maybe中的函数(最好是fromMaybe和maybe,而不是fromJust)来操作Maybe的值。
发布于 2012-12-12 14:11:26
如果您想从代码中获得一些想法,可以实现您希望实现的目标,下面是一个示例:
import Data.List (nub, maximumBy)
import Data.Function (on)
mostCommonElem list = fst $ maximumBy (compare `on` snd) elemCounts where
elemCounts = nub [(element, count) | element <- list, let count = length (filter (==element) list)]发布于 2012-12-12 14:07:09
以下是一些建议
del可以使用filter实现,而不是编写自己的递归。在你的定义中有一个错误,你在删除时需要给ys而不是y。
del x = filter (/=x)obj类似于del,但具有不同的过滤功能。类似地,在您的定义中,您需要在obj中提供ys而不是y。
obj x = filter (==x)tam只是一个length函数
-- tam = length你不需要为n1和n保留一个列表。我还使您的代码更具可读性,尽管我没有对您的算法进行任何更改。
fun n1 n [] =n1
fun n1 n xs@(x:s) | length (obj x xs) > n = fun x (length $ obj x xs) (del x xs)
| otherwise = fun n1 n $ del x xs
rep xs@(x:s) = fun x (length $ obj x xs) (del x xs)另一种不是很理想但可读性更好的方法是
import Data.List
import Data.Ord
rep :: Ord a => [a] -> a
rep = head . head . sortBy (flip $ comparing length) . group . sort我将尝试简单地解释一下这段代码是做什么的。您需要找到列表中最频繁的元素,因此首先要想到的是找到所有元素的频率。现在group是一个组合了相邻相似元素的函数。
> group [1,2,2,3,3,3,1,2,4]
[[1],[2,2],[3,3,3],[1],[2],[4]]所以我使用排序将相同的相邻元素放在一起
> sort [1,2,2,3,3,3,1,2,4]
[1,1,2,2,2,3,3,3,4]
> group . sort $ [1,2,2,3,3,3,1,2,4]
[[1,1],[2,2,2],[3,3,3],[4]]查找具有最大频率的元素仅简化为查找具有最大数量元素的子列表。下面是函数sortBy,您可以使用它根据给定的比较函数进行排序。所以基本上我已经对子列表的length进行了排序(翻转只是为了使排序降序而不是升序)。
> sortBy (flip $ comparing length) . group . sort $ [1,2,2,3,3,3,1,2,4]
[[2,2,2],[3,3,3],[1,1],[4]]现在,您只需执行两次head即可获得频率最高的元素。
https://stackoverflow.com/questions/13833017
复制相似问题