【问题标题】:Haskell - Compare two list of strings and return the number of times a word appears?Haskell - 比较两个字符串列表并返回单词出现的次数?
【发布时间】:2017-12-21 15:16:45
【问题描述】:

我是 Haskell 的初学者。我正在尝试找到一种解决方案来比较两个字符串列表并检查一个列表中的单词出现在另一个列表中的次数。

我尝试使用length 函数,但它返回列表中字符串(元素)的数量。我也使用了filter,但我不确定如何构建这个解决方案。我已查看this 网站寻求帮助,但我不确定要使用哪个功能以及如何使用。

例如,下面的代码应该返回数字 2,因为 listofStrings 包含来自 animals 的 2 个单词。

animals = ["cat", "dog", "rabbit"]
listofStrings = ["the", "cat", "bit", "the" , "dog"]

预期结果应该是:

2

【问题讨论】:

  • 你能描述一下(没有 Haskell)算法的样子吗?例如用伪代码或其他编程语言编写它?
  • 1. 创建两个字符串列表,如上所示2. 检查第二个列表和第一个列表3. 计数第一个列表中的单词出现在第二个列表中的次数,然后返回数字
  • 你有没有在hoogle?上看过任何地方?那里有一个功能可以帮助你。

标签: haskell


【解决方案1】:

您可以在as 的列表中使用filter f,其中f :: a -> Bool,并仅返回xf xTrue 的那些元素。

因此,将f 设为上面的(== x),将为您提供一个仅包含xs 的列表,重复x 在原始列表中出现的次数。

将其与length 组合,然后您会得到x 在列表中出现的次数:

countOccurencesIn xs x = length . filter (== x) $ xs

然后你想在你的第二个列表中调用它为xs,对于你的第一个列表中的每个x,这是一个map

map (countOccurencesIn ys) xs

这为您提供了一个整数列表,该列表将xs 的每个元素替换为ys 中的出现次数,那么您当然应该对这些数字求和:

finalCounter xs ys = sum . map (countOccurencesIn ys) $ xs

【讨论】:

    【解决方案2】:

    如果您的列表没有重复项,您可以使用来自Data.Listintersect 来执行此任务:

    import Data.List
    
    countWords :: (Eq a) => [a] -> [a] -> Int
    countWords xs ys = length $ intersect xs ys
    

    其工作原理如下:

    *Main> countWords ["the", "cat", "bit", "the" , "dog"] ["cat", "dog", "rabbit"] 
    2
    

    但是当列表一有重复时会遇到问题:

    *Main> countWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rabbit"]
    2
    

    上面的函数应该返回3。解决这个问题的一种方法是递归方法。我们可以先创建一个函数来过滤列表一中的元素,这些元素存在于列表二中:

    filterWords :: (Eq a) => [a] -> [a] -> [a]
    filterWords [] _ = []
    filterWords (x:xs) ys
       | x `elem` ys = x : filterWords xs ys
       | otherwise = filterWords xs ys
    

    其工作原理如下:

    *Main> filterWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rab
    bit"]
    ["cat","dog","cat"]
    

    那么我们可以只取这个结果的length

    countWords :: (Eq a) => [a] -> [a] -> Int
    countWords xs ys = length $ filterWords xs ys
    

    现在可以正常工作了:

    *Main> countWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rabbit"]
    3
    

    正如其他人所提到的,filter 使这项任务变得更加容易:

    countWords :: (Eq a) => [a] -> [a] -> Int
    countWords xs ys = length $ filter (\x -> x `elem` ys) xs
    

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多