2012-11-19 46 views
1

如何删除Haskell中字符串的第一个空格?使用Haskell删除字符串中的第一个空格

例如:

removeSpace " hello" = "hello" 

removeSpace " hello" = " hello" 

removeSpace "hello" = "hello" 
+0

是否要在t开始时只删除一个空格他字符串,字符串开头的所有空格,还是字符串中的第一个空格,即使它不是字符串中的第一个字符? –

+3

我不知道这个人究竟想要什么,但这里的第二个例子清楚地表明,这个问题与声明的重复不完全相同。投票重新开放。 –

+1

绝对如此。这个问题是关于在字符串值上使用文本函数的。那答案不会帮助user1836399多! – AndrewC

回答

6

只需使用模式匹配:

removeSpace (' ':xs) = xs 
removeSpace xs = xs 
+0

thx xD对不起,我是新来的哈斯克尔,所以.. – user1836399

11

这里有多个删除空间的选项,显示的一些功能和处事方式。

采取多的空间,你可以做

removeSpaces = dropWhile (==' ') 

这意味着相同的removeSpaces xs = dropWhile (==' ') xs,但使用部分应用程序(也是如此(==' ')本质)。

或更一般的去除,

import Data.Char 
removeWhitespace = dropWhile isSpace 

如果你真的确定你只想把一个空间(和你似乎的确如此),那么模式匹配是清晰的:

removeASpace (' ':xs) = xs -- if it starts with a space, miss that out. 
removeASpace xs = xs  -- otherwise just leave the string alone 

这是可行的,因为在haskell中,String = [Char](x:xs)表示以x开头并以列表xs进行的列表。

要删除一个空白字符,我们可以使用函数卫士(如果用很轻的语法语句中,如果您还没有见过他们):

removeAWhitespace "" = "" -- base case of empty string 
removeAWhitespace (x:xs) | isSpace x = xs -- if it's whitespace, omit it 
         | otherwise = x:xs -- if it's not keep it. 
0

随时随地在字符串中删除第一个空间:

removeSpace :: String -> String 
removeSpace = (\(xs,ys) -> xs ++ drop 1 ys) . span (/=' ') 

其中span抓取字符,直到找到空格或到达字符串的末尾。

然后分割结果并将它们放入一个我们合并的元组中,跳过第二个列表中的第一个字符(空格)。此外,我们断言剩下的不是null(空列表) - 如果是,我们不能得到尾巴,因为空列表不能有尾巴吗?所以,如果是这样,我们只是返回一个空的列表。

+0

请注意,如果空ys then [] else尾ys'可以简单地写成'drop 1 ys'。因此:'removeSpace =(\(xs,ys) - > xs ++下降1 ys)。 span(/ ='')'。 –

+0

啊,这是正确的,很好的观察 – Spinno

3

在Haskell,串字符的简单列表,即前奏定义

type String = [Char] 

此外,大约有三种方式来编写一个函数:

  1. 完全使用滚你自己您可以使用两个最基本的工具:模式匹配和递归;
  2. 巧妙地结合一些已经写好的功能;当然还有
  3. 这些的混合。

如果你是Haskell的新手和函数式编程,我推荐你用第一种方法编写大部分函数,​​然后逐渐转向使用越来越多的预定义函数。

对于你的问题 - 删除第一个空格字符(' ')在字符串模式匹配和递归实际上很有意义。如上所述,字符串只是字符列表,所以我们最终只会列出一个简单的列表遍历。

让我们先写你的函数的签名:

removeSpace :: [Char] -> [Char] 

(我已经写[Char]而不是String,清楚我们在这里执行列表遍历)

模式匹配反对一个列表,我们需要考虑两种情况:列表为空([]),列表包含头部元素后跟尾部(c : cs)。

处理空列表与往常一样简单:没有剩余字符,因此没有任何东西可以删除,我们只需返回空列表。

removeSpace [] = [] 

然后在其中我们有一个头元素(一个字符)和尾单的情况。在这里,我们需要再次区分两种情况:头部角色是空间的情况以及其他角色的情况。

如果首字符是空格,它将是我们遇到的第一个空格,我们需要将其删除。因为我们只需要删除第一空间,我们可以返回列表的其余部分(即尾)无需进一步的处理:

removeSpace (' ' : cs) = cs 

剩下的就是处理情况,其中头部角色不空间。然后我们需要将它保存在返回的列表中,此外,我们需要继续寻找列表中其余部分的第一个空间;也就是说,我们需要递归地将我们的函数应用到尾部:

removeSpace (c : cs) = c : removeSpace cs 

而就是这样。我们的函数的完整定义,现在读

removeSpace :: [Char]  -> [Char] 
removeSpace []   = [] 
removeSpace (' ' : cs) = cs 
removeSpace (c : cs) = c : removeSpace cs 

这无疑是为清晰,简明的定义,任何聪明的预定义功能相结合就会给你。

包裹起来,让我们测试功能:

> removeSpace " hello" 
"hello" 

> removeSpace " hello" 
" hello" 

> removeSpace "hello" 
"hello" 

如果你真的想构建你的功能了预定义的功能,这里是removeSpace一个另类定义,将这样的伎俩:

removeSpace :: [Char] -> [Char]  
removeSpace = uncurry (flip (flip (++) . drop 1)) . break (== ' ') 

(你可以看到为什么我使用明确的模式匹配和递归喜欢一个;-))

注:我假设你的目标确实是删除字符串中的第一个空格,而不管第一个空格出现在哪里。在你给出的例子中,第一个空格总是字符串中的第一个字符。如果情况总是如此,即,如果你只删除一个前导空格之后,你可以离开了递归和简单的写

removeSpace :: [Char]  -> [Char] 
removeSpace []   = [] 
removeSpace (' ' : cs) = cs 
removeSpace (c : cs) = c : cs 

或者,结合第一个和最后的情况下,

removeSpace :: [Char]  -> [Char] 
removeSpace (' ' : cs) = cs 
removeSpace cs   = cs 

或使用预定义功能,

removeSpace :: [Char] -> [Char] 
removeSpace = uncurry ((++) . drop 1) . span (== ' ')