如何使用给定数字缩短Haskell中的字符串。
说:
comp :: String -> String
short :: String -> String
chomp (x:xs) = (x : takeWhile (==x) xs)
使用comp
我想从字符串的开头选择一系列重复字符
包含最多九个字符的运行。
例如:
short "aaaavvvdd"
输出"aaaa"
和short "dddddddddd"
输出"ddddddddd"
。
我知道我需要take
,但我不确定如何将其放入代码中。
我已经做到这一点,但它不起作用
short x:xs | length(short x:xs) >9 = take(9)
| otherwise = comp
答案 0 :(得分:9)
import Data.List
short [] = []
short x = (take 9 . head . group) x
这将为您提供与您想要的输出匹配的输出。
即,
*> short "aaaavvvdd"
"aaaa"
*> short "dddddddddd"
"ddddddddd"
此解决方案取决于Data.List库中的“group”函数。我们从定义开始:
short x = group x
这给了我们:
*> short "aaaavvvddd"
["aaaa","vvv","ddd"]
一旦我们拥有列表中的元素,我们只需要列表的第一项。我们使用“head”来实现这一目标:
short x = (head . group) x
“”。是函数组合的Haskell函数。它与:
相同short x = head (group x)
或
short x = head $ group x
这将给我们:
*> short "aaaavvvdd"
"aaaa"
*> short "dddddddddddddd"
"dddddddddddddd"
我们只通过这个结果的前九个字符完成程序,最后得到我们的最终功能。为此,我们使用前奏中的“take”函数:
short x = (take 9 . head . group) x
我们现在得到了我们想要的结果,但有一个小问题。
请注意,在空列表中使用我们当前的定义会导致错误,
*> short "aaaavvvddd"
"aaaa"
*> short ""
"*** Exception: Prelude.head: empty list
因为在空列表中未定义“head”,我们需要处理另一种情况:空列表。现在我们有:
short [] = []
short x = (take 9 . head . group) x
这是我们的“最终答案”。
答案 1 :(得分:4)
这是另一个版本:
short xs = take 9 $ takeWhile (== head xs) xs
所以我们从列表中取出,只要内容等于列表的头部(这是字符串的第一个字符串)。然后我们使用take
在必要时缩短结果。
请注意,我们不需要空字符串的附加案例,这是Haskell的懒惰的结果:如果takeWhile
看到list参数为空,则不会无法评估条件参数,因此head xs
不会抛出错误。
答案 2 :(得分:3)
这是一个定义:
import Data.List (group)
short = take 9 . head . group
有趣的是,由于我们返回的字符串是原始字符串的前缀,并且被限制为最多9个字符长,因此我们是否先减少到该限制并不重要。所以我们也可以使用这个定义:
short = head . group . take 9
这两种都是以“无点”的方式编写的,它没有引用缺少标点符号,而是缺少不必要的变量。我们也可以将定义写成
short s = take 9 (head (group s))
或者,使用$
删除括号:
short s = take 9 $ head $ group s
唯一的另一个步骤是仅提取第一个匹配字符块,这是head . group
所做的(相当于您的chomp
函数)。
来自the docs:
group :: Eq a => [a] -> [[a]]
group
函数接受一个列表并返回一个列表列表,使得结果的串联等于参数。此外,结果中的每个子列表仅包含相同的元素。例如,group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]
这是
groupBy
的一个特例,它允许程序员提供自己的相等测试。