List 字符串到押韵词列表
我的目标是一个函数,它接受一个句子并返回一个列表,其中包含单词rhyming(rhyming=最后3个字符相等) 示例:List 字符串到押韵词列表,list,haskell,List,Haskell,我的目标是一个函数,它接受一个句子并返回一个列表,其中包含单词rhyming(rhyming=最后3个字符相等) 示例:“六个生病的乡巴佬用镐和棍子砍了六块光滑的砖头。”-> [[Six,six],[sick,nick,slick],[hicks,bricks,picks,sticks],[with]] 这是到目前为止我的代码(bsort是bubblesort): 我不知道如何将其翻译成代码,但我想获取第一个字符串的前三个字符,并将它们放入一个列表中。然后取下一个字符串并测试它是否等于第一个字
“六个生病的乡巴佬用镐和棍子砍了六块光滑的砖头。”
->
[[Six,six],[sick,nick,slick],[hicks,bricks,picks,sticks],[with]]
这是到目前为止我的代码(bsort是bubblesort):
我不知道如何将其翻译成代码,但我想获取第一个字符串的前三个字符,并将它们放入一个列表中。然后取下一个字符串并测试它是否等于第一个字符串。如果为true,则将第二个字符串放入第一个列表,否则创建第二个列表。然后转到第三个字符串,每次都使用前面的列表进行测试
有人能帮我吗?当您必须将项目分组在一起时,可以使用的分组高阶函数。通过编写分组函数,您可以轻松解决问题。在您的例子中,您希望将押韵的单词组合在一起。您只需编写函数
押韵
:
rhyming :: String -> String -> Bool
rhyming word1 word2 = last3 (lower word1) == last3 (lower word2)
where
last3 = take 3 . reverse -- if you wanted `last3` to return the last three characters in order, you'd just have to apply `reverse` to the result, but that's unnecessary here
lower = map toLower
因此,您的韵词
函数可以这样编写:
import Data.List (groupBy, sort)
import Data.Char (toLower)
rhyming :: String -> String -> Bool
rhyming word1 word2 = last3 (lowercase word1) == last3 (lowercase word2)
where
last3 = take 3 . reverse
lowercase = map toLower
rhymeWords :: String -> [[String]]
rhymeWords = groupBy rhyming . map reverse . sort . map reverse . words
映射反向。分类由于groupBy
将相邻的元素分组,因此需要映射反向。它将可能押韵在一起的单词分组。以下代码按要求分组押韵,尽管它将所有字符转换为小写
import Data.List (sort)
import Data.Char (toLower)
rhymeWords:: String -> [[String]]
rhymeWords "" = []
rhymeWords xs = [map reverse g | g <- groupRhymes (sortRhymes xs) []]
where sortRhymes xs = sort $ map reverse (words [toLower x | x <- xs])
groupRhymes :: [String] -> [[String]] -> [[String]]
groupRhymes [] acc = acc
groupRhymes (x:xs) acc = case acc of
[] -> groupRhymes xs [[x]]
_ -> if take 3 x == take 3 (head (last acc))
then groupRhymes xs ((init acc) ++ [(last acc) ++ [x]])
else groupRhymes xs (acc ++ [[x]])
请注意,示例输入在句子末尾没有句点,因为最后一个单词将包含句点并中断排序。如果你需要传递带句号的句子,你需要稍微修改一下呈现的代码。你可以从押韵
函数中删除反向
部分,并从押韵词
中删除第一个映射反向
。他们有点“互相抵消”。除此之外,还有一个不错的答案(比我提出的答案可读性强得多)。我刚开始尝试使用groupBy
,但失败了…谢谢你的回答!:由于押韵
和押韵词
是两个独立的功能,它们需要是“独立的”。我的意思是,他们应该在任何条件下工作。但是,如果我将押韵
函数放在where子句
中,它会更有意义,因为它只存在于押韵词
的上下文中。回答也很好:)@baxbaxwalanuksiwe感谢您的澄清。是:\s->elems的一个小变体。fromListWith(++)$[(取3(反向w),[w])| w谢谢!现在就摆弄吧!:)
import Data.List (sort)
import Data.Char (toLower)
rhymeWords:: String -> [[String]]
rhymeWords "" = []
rhymeWords xs = [map reverse g | g <- groupRhymes (sortRhymes xs) []]
where sortRhymes xs = sort $ map reverse (words [toLower x | x <- xs])
groupRhymes :: [String] -> [[String]] -> [[String]]
groupRhymes [] acc = acc
groupRhymes (x:xs) acc = case acc of
[] -> groupRhymes xs [[x]]
_ -> if take 3 x == take 3 (head (last acc))
then groupRhymes xs ((init acc) ++ [(last acc) ++ [x]])
else groupRhymes xs (acc ++ [[x]])
hymeWords "Six sick hicks nick six slick bricks with picks and sticks"
[["and"],["with"],["slick","nick","sick"],["hicks","picks","bricks","sticks"],["six","six"]]