【问题标题】:Process a string using foldr where '#' means deleting the previous character使用 foldr 处理字符串,其中“#”表示删除前一个字符
【发布时间】:2021-12-31 23:10:21
【问题描述】:

我需要使用foldr 处理字符串,其中'#' 表示删除前一个字符。例如:

>backspace "abc#d##c"
"ac"

>backspace "#####"
""

需要使用foldr 遍历列表,而不使用reverse 和/或(++)

这是我到目前为止所得到的:

backspace :: String -> String
backspace xs = foldr func [] xs where
  func c cs | c /= '#' = c:cs
            | otherwise = cs

但它只是从字符串中过滤'#'。我想每次c == '#' 都删除当前答案的最后一个元素并得到类似的东西

backspace :: String -> String
backspace xs = foldr func [] xs where
  func c cs | c /= '#' = c:cs
            | cs /= [] = init cs
            | otherwise = cs

但它不能正常工作,

ghci> backspace "abc#d##c" 
"abc"

【问题讨论】:

  • 您可能不需要reverse,因为foldr 从右侧反向操作。您是否被告知 foldr 应该直接返回实际字符​​串?或者foldr 可能会返回一些最终的state,您可以从中轻松提取实际字符串?

标签: list haskell fold


【解决方案1】:

您可以使用(Int, String) 作为foldr 的状态,其中第一个Int 是退格数,String 是当前构造的字符串。

这意味着您可以使用:

backspace :: String -> String
backspace = snd . foldr func (0, [])
  where func '#' (n, cs) = (n+1, cs)
        func c (n, cs)
                 | n > 0 = …      -- (1)
                 | otherwise = …  -- (2)

如果我们有一个字符不是#,而是n > 0,这意味着我们需要删除该字符,因此忽略c并减少n。如果是n == 0,我们可以将c 添加到String

我将填写 部分作为练习。

【讨论】:

    猜你喜欢
    • 2011-03-14
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 2014-07-17
    • 1970-01-01
    • 2023-03-14
    • 2011-05-16
    相关资源
    最近更新 更多