Haskell - 检查列表是否包含元素至少 N 次
Haskell - Checking if a list contains an element atleast N times
我正在编写一个函数来检查列表是否包含某个元素至少 N 次
atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a l = n <= (sum [1 | x <- l, (x == a)])
有限列表工作正常,但我正在努力使它适用于无限列表,例如:
atLeastNtimes 100 'a' (repeat 'a')
以下是一些可能的替代方法:
递归定义您的函数,无需检查完整列表,只检查所需的前缀。
首先 filter
编辑列表,以便仅保留要计算的元素。然后,使用 drop (n-1) xs
删除 n-1
个元素(如果有),并检查结果列表是否不为空(使用 null
)。请注意 drop
ping 比列表中更多的元素不是错误,它会导致一个空列表。
我们可以把问题分成两部分。第一个只是检查列表是否足够长。
-- | Check whether the length of a list
-- is at least a certain value.
lengthAtLeast :: Int -> [a] -> Bool
lengthAtLeast n0 xs0 = foldr go stop xs0 n0
where
stop n = n <= 0
go _ _ n | n <= 0 = True
go _ r n = r (n - 1)
第二个是过滤,filter
为您完成。所以
atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a = lengthAtLeast n . filter (a ==)
我正在编写一个函数来检查列表是否包含某个元素至少 N 次
atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a l = n <= (sum [1 | x <- l, (x == a)])
有限列表工作正常,但我正在努力使它适用于无限列表,例如:
atLeastNtimes 100 'a' (repeat 'a')
以下是一些可能的替代方法:
递归定义您的函数,无需检查完整列表,只检查所需的前缀。
首先
filter
编辑列表,以便仅保留要计算的元素。然后,使用drop (n-1) xs
删除n-1
个元素(如果有),并检查结果列表是否不为空(使用null
)。请注意drop
ping 比列表中更多的元素不是错误,它会导致一个空列表。
我们可以把问题分成两部分。第一个只是检查列表是否足够长。
-- | Check whether the length of a list
-- is at least a certain value.
lengthAtLeast :: Int -> [a] -> Bool
lengthAtLeast n0 xs0 = foldr go stop xs0 n0
where
stop n = n <= 0
go _ _ n | n <= 0 = True
go _ r n = r (n - 1)
第二个是过滤,filter
为您完成。所以
atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a = lengthAtLeast n . filter (a ==)