字符串到押韵单词列表

时间:2015-11-22 20:21:38

标签: list haskell

我的目标是一个函数,它接受一个句子并返回一个列表,其中包含单词押韵(押韵=最后3个字符相等)。

示例:flex - >

"Six sick hicks nick six slick bricks with picks and sticks."

这是我到目前为止的代码(bsort是bubblesort):

[[Six,six],[sick,nick,slick],[hicks,bricks,picks,sticks],[with]]

我不知道如何将其翻译成代码,但我想把第一个字符串的前三个字符放入列表中。然后取下一个String并测试它是否等于第一个。如果为true,则将第二个字符串放入第一个列表,否则创建第二个列表。然后转到第三个字符串,每次使用以前的列表进行测试。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

如果必须将项目组合在一起,则可以使用Data.List对更高阶的功能进行分组。使用groupBy,您只需编写分组功能即可轻松解决问题。在你的情况下,你想组合押韵的词。您只需编写函数rhyming

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

所以你的rhymeWords函数可以像这样编写:

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

由于map reverse . sort . map reverse对彼此相邻的元素进行分组,因此需要groupBy。它将可能押韵的词汇分组。

答案 1 :(得分:1)

以下代码组按要求押韵,但它将所有字符转换为小写。

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"]]

请注意,示例输入在句子末尾没有句号,因为最后一个单词会包含它并打破排序。如果你需要传递句点句子,你需要在提供的代码中稍微改变一下。