【问题标题】:How to split a list of numbers into a set of list with all the numbers in Haskell如何将数字列表拆分为一组包含 Haskell 中所有数字的列表
【发布时间】:2019-03-28 14:52:30
【问题描述】:

如何仅通过前奏的递归和函数将Haskell中的列表(例如“222 33244”)拆分为[“222”,“33”,“2”,“444”]?

我目前的尝试是:

list xs
  |length xs == 0 = ""
  |otherwise = listSplit xs

 listSplit (x:xs)
  |x == head xs = x : ListSplitNext x xs
  |otherwise = x:[]

 listSplitNext a (x:xs)
  |a == x = a : listSplitNext x xs
  |otherwise = listSplit xs

【问题讨论】:

标签: string list haskell recursion


【解决方案1】:

因此,由于我不太了解您的方法,并且 ghci 在您的代码中列出了 18 个编译错误,因此恐怕无法帮助您尝试解决方案。

正如评论中指出的,一个可能的解决方案是:

listSplit xs = listSplit' [] (filter (`elem` ['0'..'9']) xs)

listSplit' ws (x:xs) = listSplit' (ws ++ [x : takeWhile (==x) xs]) (dropWhile (==x) xs)
listSplit' ws [] = ws
  1. 过滤字符串中不是数字的每个元素(Data.Char.isNumber 也会这样做,但前提是只使用 Prelude 函数)并在过滤后的列表上调用 listSplit'

  2. (ws ++ [x : takeWhile (==x) xs]) 收集 xs 中的所有内容,直到遇到不等于 x 的字母,将其包装在列表中并将其附加到 ws

  3. (dropWhile (==x) xs) 删除 xs 中的每个字母,直到它到达不等于 x 的字母。

  4. 最后,函数使用更新后的ws 和缩减后的xs 调用自身

  5. 如果没有剩余元素,函数返回ws

【讨论】:

    【解决方案2】:

    如果您的目标是使用很少的预定义函数,这可能会给您一些想法:

    listSplit :: String -> [String]
    listSplit xs =
      let (as, a) = foldr go ([], []) numbers
      in  a : as
     where
      isNumber x = x `elem` ['0'..'9']
      numbers    = filter isNumber xs
    
      go cur (res, []) = (res, [cur])
      go cur (res, lst@(a:_))
        | a == cur  = (res, a : lst)
        | otherwise = (lst : res, [cur])
    

    当然你也可以用你自己的递归替换foldr

    numberSplit :: String -> [String]
    numberSplit xs =
      let numbers = filter (`elem` ['0'..'9']) xs
      in  listSplit numbers
    
    
    listSplit :: Eq a => [a] -> [[a]]
    listSplit =
      reverse . go [] []
     where
      go acc as [] = as : acc
      go acc [] (x:xs) = go acc [x] xs
      go acc as@(a:_) (x:xs)
        | a == x    = go acc (a : as) xs
        | otherwise = go (as : acc) [x] xs
    

    【讨论】:

      【解决方案3】:

      我有时间来实现它,但我认为这就是您正在寻找的。​​p>

      listSplit s = go filtered
        where filtered = [c | c <- s, elem c ['0'..'9']]
              go [] = []
              go (x:xs) = (x : takeWhile (== x) xs) : (go $ dropWhile (== x) xs)
      

      【讨论】:

        猜你喜欢
        • 2017-09-28
        • 2018-12-30
        • 2023-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        • 1970-01-01
        • 2012-03-24
        相关资源
        最近更新 更多