假设我有两个整数列表:
4 12 24 26 35 41
42 24 4 36 2 26
两个名单之间有3场比赛。
如何计算Haskell中任意两个列表之间的匹配数?
感谢。
答案 0 :(得分:10)
如果您不需要处理多个元素,那么简单的方法就是计算交叉点的长度
import Data.List
matches :: Eq a => [a] -> [a] -> Int
matches xs ys = length (intersect xs ys)
如果您还有一个Set
实例,使用Ord
作为中间结构会更有效:
import qualified Data.Set as S
matches :: Ord a => [a] -> [a] -> Int
matches xs ys = S.size (S.intersection (S.fromList xs) (S.fromList ys))
如果你需要注意重复,使用Map
计算每个元素的出现次数将是一个不太难的修改。
答案 1 :(得分:6)
对于列表来说会非常痛苦,因为你需要通过它们来完成所有对。像这样的东西通过形成它们相等的所有对来打印出正确答案,然后计算尺寸。
let xs = [1,2,3,4]
let ys = [1,2,3,4]
length [x | x <- xs, y <- ys, x == y]
从性能的角度来看,这样做很尴尬。对于大型列表,您最好使用一个集合,因为您可以更快地测试成员资格(通常为O(lg N),有时为O(1)),而不是列表(O(N))。
答案 2 :(得分:2)
来自intersect
的函数Data.List
返回两个给定列表之间的交集。
import Data.List (intersect)
numberOfIntersections :: (Eq a) => [a] -> [a] -> Int
numberOfIntersections xs ys = length $ intersect xs ys
main = do
print $ numberOfIntersections [4, 12, 24, 26, 35, 41] [42, 24, 4, 36, 2, 26]
答案 3 :(得分:1)
如果您想要一个仅使用列表的解决方案,这个列表不会像Data.List.intersect
那么慢,您可以使用它:
intersectSorted [] _ = []
intersectSorted _ [] = []
intersectSorted (x : xs) (y : ys) = case compare x y of
LT -> intersectSorted xs (y : ys)
EQ -> x : intersectSorted xs ys
GT -> intersectSorted (x : xs) ys
intersect a b = intersectSorted (sort a) (sort b)