【问题标题】:How many elements are the same in two lists (haskell)两个列表中有多少元素相同(haskell)
【发布时间】:2016-03-22 12:51:56
【问题描述】:

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

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

"t" 和 "k" 是两个列表的一部分,所以返回值为 2。我怎样才能在不使用任何库和使用递归的情况下实现这个函数?

【问题讨论】:

  • 是否应该处理重复项?
  • ...或者您基本上将列表视为集合? (有a better type for those。)
  • @Shoe 不会有重复的元素,所以应该不会。
  • 你到底尝试了什么?
  • 我投票决定将此问题作为题外话结束,因为做你的作业不是我们的工作。非工作代码应包含在问题的主体中,并说明它应该做什么以及它正在做什么。

标签: list haskell functional-programming


【解决方案1】:

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

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

Live demo

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


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

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

Live demo

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

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

Live demo

如果您不想使用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

Live demo

【讨论】:

  • 感谢您的回复,但我不想使用任何库。我想在不使用模块的情况下实现。我尝试使用递归来做到这一点。
【解决方案2】:

不使用任何额外的函数,您可以简单地编写如下

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'

本质上,您将手动执行的方式,比较前两个元素,如果相同,则增加计数器并移动两个列表中的下一个元素。如果不相等,则将第一个列表的第一个元素与第二个列表的其余部分进行比较,并将第一个列表的其余部分与第二个列表进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多