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
如果列表中没有重复项,可以使用fromData.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
如果列表中没有重复项,可以使用fromData.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检查第二个列表。数一数第一个列表中的单词出现在第二个列表中的次数,然后返回数字。如果您在任何位置查找过,则有一个函数可能会对您有所帮助。