【问题标题】:Replacing a string in Haskell在 Haskell 中替换字符串
【发布时间】:2014-01-29 03:42:35
【问题描述】:

我正在尝试用 Haskell 中的另一个字符串替换一个字符串。这是我到目前为止的代码,但它并不完全有效。

replace :: [Char] -> [Char]
replace [] = []
replace (h:t) =
    if h == "W"
    then "VV" : replace t
    else h : replace t

我希望能够做到这一点,例如:如果字符串是“HELLO WORLD”,结果应该是“HELLO VVORLD”。我认为 words/unwords 会有所帮助,但不完全确定如何实现它。

【问题讨论】:

  • 除了J.Abrahamsonthe answer here 中提供的内容,请仔细阅读函数中的类型。您使用[Char],这意味着它只能使用Chars,而不能使用其他任何东西。还要注意(:) 的类型。是的,Haskell 很有趣! :-)

标签: string haskell replace


【解决方案1】:

值得明确说明String 究竟是什么。例如,您正在寻找测试用例:

replace ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D']
==
['H', 'E', 'L', 'L', 'O', ' ', 'V', 'V', 'O', 'R', 'L', 'D']

现在,当您在这样的列表上进行模式匹配时,列表的开头将是字符串的第一个 字符

> case "Hello world" of (c:rest) -> print c
'H'

所以我们不能将它与像"W" 这样的字符串文字匹配。类似地,我们不能使用 cons ((:)) 将一个字符串附加到另一个字符串,我们只能添加一个字符!

> 'P' : "hello"
"Phello"

相反,我们将使用(++) :: String -> String -> String 附加两个字符串。

replace :: [Char] -> [Char]
replace [] = []
replace (h:t) =
    if h == 'W'
      then "VV" ++ replace t
      else h : replace t

应该按预期工作

> replace "Hello World"
"Hello VVorld"

【讨论】:

  • ++ 的运行时间是多少?将两个字符都取而代之,'V' : 'V' : replace t 不是有益的吗?
  • (++) 在其左参数的大小上是线性的,所以在这里几乎是一样的。考虑到 GHC 应用于常量,GHC 甚至可能会完全内联 (++)
  • 不,这主要取决于仅扩展字符的想法。您需要某种滑动窗口来实现单词替换。
【解决方案2】:

使用模式匹配:

replace ('W':xs) = "VV" ++ replace xs
replace (x:xs) = x : replace xs
replace [] = []

用于理解:

replace xs = concat [if x == 'W' then "VV" else [x] | x <- xs]

使用单子:

replace = (>>= (\ x -> if x == 'W' then "VV" else [x]))

折叠:

replace = foldr (\ x -> if x == 'W' then ("VV"++) else (x:)) []

【讨论】:

    【解决方案3】:

    错误在"VV" :: [Char],但不在Char

    "W"[Char],但不是Char

    replace :: [Char] -> [Char]
    replace [] = []
    replace (h:t) =
        if h == 'W'
        then 'V' : 'V' : replace t
        else h : replace t
    

    【讨论】:

    • 谢谢,还有一个简单的问题,我该如何修改它来替换单词。例如,如果输入字符串是:“我来自美国”,我想将“美国”替换为“澳大利亚”,那么结果应该是“我来自澳大利亚”。
    • @user3247171 那你应该用兰黛回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2013-04-29
    • 2012-02-28
    相关资源
    最近更新 更多