List 两个列表中有多少元素相同(haskell)

List 两个列表中有多少元素相同(haskell),list,haskell,functional-programming,List,Haskell,Functional Programming,我试图了解在给定的两个集合中有多少元素是相同的。说清楚了, let a = ["t","k","m"] let b = ["k","b","t","c"] “t”和“k”是两个列表的一部分,因此返回值为2。如何在不使用任何库和递归的情况下实现此函数?您可以使用模块Data.Set将两个列表转换为集合,并计算交叉点的大小: let a = Set.fromList ["t","k","m"] let b = Set.fromList ["k","b","t","c"] print $ Set.s

我试图了解在给定的两个集合中有多少元素是相同的。说清楚了,

let a = ["t","k","m"]
let b = ["k","b","t","c"]

“t”和“k”是两个列表的一部分,因此返回值为2。如何在不使用任何库和递归的情况下实现此函数?

您可以使用模块
Data.Set
将两个列表转换为集合,并计算交叉点的大小:

let a = Set.fromList ["t","k","m"]
let b = Set.fromList ["k","b","t","c"]
print $ Set.size (a `Set.intersection` b)

作为一般规则,如果列表中元素的顺序无关紧要,并且列表中不包含重复项,则最好将其转换为


由于某些原因,您不想使用标准库。如果您不关心算法复杂性,则可以使用:

length $ Prelude.filter (`elem` b) a

当然,如果你想把它变成递归形式,那么它是这样的:

countDuplicates :: (Eq a) => [a] -> [a] -> Int
countDuplicates [] b = 0
countDuplicates (x:rest) b =
    let index = if x `elem` b then 1 else 0
    in index + countDuplicates rest b

如果您不想使用
elem
,则这两个选项都将进一步扩展为:

countDuplicates :: (Eq a) => [a] -> [a] -> Int
countDuplicates [] b = 0
countDuplicates (x:rest) b =
    let myElem a [] = False
        myElem a (al:lst) = if a == al then True else myElem a lst
        index = if x `myElem` b then 1 else 0
    in index + countDuplicates rest b

无需使用任何额外的函数,您只需按如下方式编写

countIntersect :: (Eq a) => [a] -> [a] -> Int
countIntersect _ [] = 0
countIntersect [] _ = 0
countIntersect (x:xs) y'@(y:ys) | x==y = 1 + countIntersect xs ys
                                | otherwise = countIntersect [x] ys + countIntersect xs y'

从本质上讲,就像您手工操作一样,比较前两个元素(如果相同),增加计数器并移动两个列表中的下一个元素。如果不相等,则将第一个列表的第一个元素与第二个列表的其余部分进行比较,并将第一个列表的其余部分与第二个列表进行比较