消除字符串中的连续重复项

13 haskell

我想从字符串中消除连续的重复项,例如f "aaabbbcccdeefgggg" = "abcdefg"

这是我的代码

f :: String -> String
f "" = ""
f "_" = "_"
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)
Run Code Online (Sandbox Code Playgroud)

我收到错误非详尽模式,我认为它来自第二行,程序不知道当只剩下 1 个字符时如何处理。我应该如何修复它?

Wil*_*sem 23

"_"模式不匹配带有任何字符的字符串,它匹配包含下划线的字符串。

您可以将[_]其用作单例字符串的模式,因此:

f :: String -> String
f "" = ""
f s@[_] = s
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)
Run Code Online (Sandbox Code Playgroud)

这里我们使用s@捕获一个字符作为 的字符串s

或者我们可以这样简化:

f :: String -> String
f (x : xs : xss)
    | x == xs   = f (xs : xss)
    | otherwise = x : f (xs : xss)
f s = s
Run Code Online (Sandbox Code Playgroud)


Enr*_*lis 16

我想从字符串中消除连续的重复项,例如f "aaabbbcccdeefgggg" = "abcdefg"

您可以将相等的字母分组(通过Data.List.group),然后取每组的第一个(通过map head,它适用head于列表的每个元素并返回结果列表):

import Data.List (group) -- so we write group instead of Data.List.group
map head $ group "aaabbbcccdeefgggg"
Run Code Online (Sandbox Code Playgroud)

这可以看作是在对输入应用map head 应用。因此,您可以像这两个函数的组合一样定义:groupStringf

f :: String -> String
f = map head . group
Run Code Online (Sandbox Code Playgroud)

为了完整起见,由于您似乎是 Haskell 的新手,因此以下是一些详细信息:

  • Data.List.group "aaabbbcccdeefgggg"返回["aaa","bbb","ccc","d","ee","f","gggg"]
  • f $ a b c是相同的f (a b c);
  • .是复合运算符,并且它使得(f . g) x == f (g x).
    • 与这个问题无关,但一般要记住,它对.一元函数进行操作,这意味着如果g采用多个参数,则只要给出一个参数,组合就会将部分应用g到管道。换句话说,如果是,比如说,二进制,那么不等于,这通常甚至不会编译,而是等于。关于此的更多示例,但在 JavaScript 中,位于我的这个答案中,对于 Haskell 程序员来说应该具有相当的可读性。ff . ggf (g x y)(f . g) x y((f .) . g) x y


bip*_*pll 7

或者,如果你不处理那些可以不处理的事情,你可以让它变得更简单:

f :: String -> String
f (x:y:xs) | x == y = f (y:xs)
f (x:xs) = x:f xs
f _ = ""
Run Code Online (Sandbox Code Playgroud)