Haskell-比较两个字符串列表并返回单词出现的次数?

Haskell-比较两个字符串列表并返回单词出现的次数?,haskell,Haskell,我是哈斯克尔的初学者。我试图找到一个解决方案,来比较两个字符串列表,并检查一个列表中的单词在另一个列表中出现了多少次 我尝试使用length函数,但它返回列表中字符串(元素)的数量。我还使用了过滤器,但我不确定如何构建此解决方案。我已经检查了网站的帮助,但我不确定该使用哪个功能以及如何使用 例如,下面的代码应该返回数字2,因为ListOfstring包含两个来自动物的单词 预期结果应为: 2 您可以在as列表上使用filter f,其中f::a->Bool,并仅返回f x为真的元素x 因此,将

我是哈斯克尔的初学者。我试图找到一个解决方案,来比较两个字符串列表,并检查一个列表中的单词在另一个列表中出现了多少次

我尝试使用
length
函数,但它返回列表中字符串(元素)的数量。我还使用了
过滤器
,但我不确定如何构建此解决方案。我已经检查了网站的帮助,但我不确定该使用哪个功能以及如何使用

例如,下面的代码应该返回数字2,因为ListOfstring包含两个来自动物的单词

预期结果应为:

2

您可以在
a
s列表上使用
filter f
,其中
f::a->Bool
,并仅返回
f x
真的
元素
x

因此,将上面的
f
设为
(==x)
,将给出一个仅由
x
s组成的列表,重复原始列表中出现
x
的次数

length
组合此项,然后给出列表中出现
x
的次数:

countOccurencesIn xs x = length . filter (== x) $ xs
然后,对于第一个列表中的每个
x
,您希望使用第二个列表将其称为
xs
,这是一个
映射:

map (countOccurencesIn ys) xs
这将为您提供一个整数列表,这些整数是将
xs
的每个元素替换为它在
ys
中出现的次数而得到的,然后您当然应该将这些数字相加:

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

您可以在
a
s列表上使用
filter f
,其中
f::a->Bool
,并仅返回
f x
真的
元素
x

因此,将上面的
f
设为
(==x)
,将给出一个仅由
x
s组成的列表,重复原始列表中出现
x
的次数

length
组合此项,然后给出列表中出现
x
的次数:

countOccurencesIn xs x = length . filter (== x) $ xs
然后,对于第一个列表中的每个
x
,您希望使用第二个列表将其称为
xs
,这是一个
映射:

map (countOccurencesIn ys) xs
这将为您提供一个整数列表,这些整数是将
xs
的每个元素替换为它在
ys
中出现的次数而得到的,然后您当然应该将这些数字相加:

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

如果列表中没有重复项,可以使用from
Data.List
执行此任务:

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> filterWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rab
bit"]
["cat","dog","cat"]
但当列表1中有重复项时会遇到问题:

*Main> countWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rabbit"]
2
上述函数应已返回
3
。解决这个问题的一种方法是递归方法。我们可以首先制作一个函数,从列表1中筛选元素,该元素存在于列表2中:

filterWords :: (Eq a) => [a] -> [a] -> [a]
filterWords [] _ = []
filterWords (x:xs) ys
   | x `elem` ys = x : filterWords xs ys
   | otherwise = filterWords xs ys
其工作原理如下:

*Main> countWords ["the", "cat", "bit", "the" , "dog"] ["cat", "dog", "rabbit"] 
2
*Main> filterWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rab
bit"]
["cat","dog","cat"]
然后我们可以取这个结果的
长度

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

如果列表中没有重复项,可以使用from
Data.List
执行此任务:

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> filterWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rab
bit"]
["cat","dog","cat"]
但当列表1中有重复项时会遇到问题:

*Main> countWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rabbit"]
2
上述函数应已返回
3
。解决这个问题的一种方法是递归方法。我们可以首先制作一个函数,从列表1中筛选元素,该元素存在于列表2中:

filterWords :: (Eq a) => [a] -> [a] -> [a]
filterWords [] _ = []
filterWords (x:xs) ys
   | x `elem` ys = x : filterWords xs ys
   | otherwise = filterWords xs ys
其工作原理如下:

*Main> countWords ["the", "cat", "bit", "the" , "dog"] ["cat", "dog", "rabbit"] 
2
*Main> filterWords ["the", "cat", "bit", "the" , "dog", "cat"] ["cat", "dog", "rab
bit"]
["cat","dog","cat"]
然后我们可以取这个结果的
长度

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
你能描述一下(没有Haskell)算法的样子吗?例如,用伪代码或其他编程语言1编写。创建两个字符串列表,如上图2所示。用第一个列表3检查第二个列表。数一数第一个列表中的单词在第二个列表中出现的次数,然后返回数字如果您在其中的任何位置查找了函数,可能会对您有所帮助。您能描述一下(没有Haskell)算法的情况吗?例如,用伪代码或其他编程语言1编写。创建两个字符串列表,如上图2所示。用第一个列表3检查第二个列表。数一数第一个列表中的单词出现在第二个列表中的次数,然后返回数字。如果您在任何位置查找过,则有一个函数可能会对您有所帮助。