【问题标题】:Transform a string into a list of substrings describing sequences将字符串转换为描述序列的子字符串列表
【发布时间】:2019-03-13 11:26:35
【问题描述】:

我正在尝试将一个字符串拆分为一个序列列表,这些序列是该字符串的子字符串。这有点难以解释,但我会给你一个例子,这样你就可以理解我在寻找什么。

从这个字符串"123456789",我想得到一个这样的列表:

["123", "234, "345, ..., "789", "891", "912"]

目前,我只有一个函数,可以将字符串拆分为该字符串的n 部分列表:

splitList :: Int -> [a] -> [[a]]
splitList _ [] = []
splitList n xs = as : splitList n bs
    where (as,bs) = splitAt n xs

【问题讨论】:

    标签: string list haskell split sequence


    【解决方案1】:

    我会使用 takedrop 的组合,以及列表理解:

    splitList :: Int -> [a] -> [[a]]
    splitList n xs = [take n $ drop i $ xs ++ xs | i <- [0..(length xs - 1)]]
    

    xs ++ xs 只是为了获得“循环”效果,它可以调整为仅添加前 (n-1) 个元素,但我相信 Haskell 的懒惰应该意味着这样做不会降低效率这样)

    【讨论】:

    • 非常感谢!它没有做一个完整的“圈子”(“891”、“912”不在列表中),但我会尝试解决这个问题。再次感谢,祝你有美好的一天:)
    • 哎呀,那是因为我只是在后期才注意到“循环”,并更新了它从中获取的列表,但没有更新理解中的索引。我现在就这样做。 [编辑:完成]
    • 我不是这种方法的忠实拥护者。相反,我会尝试调整take n &lt;$&gt; tails xs,以便最后的最短列表不会出现。这也可以避免上述方法所具有的二次复杂度 wrtlength xs
    • 要考虑的边缘情况:如果n &gt; 2*length xs
    • 你说得对,当n 变得太大时,这将无法正常运行(事实上n &gt; length xs 足以将其搞砸,据我所知)。我承认我只是匆匆写下了脑海中突然出现的第一件事,而没有完全考虑清楚。考虑到您和 Will 已经添加了更好的答案,我增加更多复杂性来尝试挽救这一点毫无意义——但我将把它留在这里,因为我认为展示一个在大多数情况下都有效的“幼稚”解决方案是有价值的,因为以及有价值的cmets指出缺陷。
    【解决方案2】:

    我会这样做:

    import Data.List
    splitList n xs = zipWith const chunks xs where
        chunks = map (take n) . tails . cycle $ xs
    

    这应该有复杂度O(m*n),其中m是xs的长度,n是每个块的大小;天真地似乎很难做得比这更好,因为这是输出的大小。它还巧妙地处理了许多尴尬的边缘情况,包括在无限列表输入上的合理工作。

    如果您以前没有见过 zipWith const 技巧,那么它绝对是值得添加到您的武器库中的一项。它可以让您做与take (length xs) ys 大致相同的事情,但无需事先实际计算length xs

    【讨论】:

    • 感谢您提供有关zipWith const 的提示,我必须承认我当时一直在思考“zipWith const xs ysxs 不一样吗?”在我看到你的解释之前,我的光芒慢慢地亮了:)
    【解决方案3】:
    splitList :: Int -> [a] -> [[a]]
    splitList n xs = zipWith const (map (take n) . tails . cycle $ xs) xs
    
    -- splitList n = zipWith const =<< map (take n) . tails . cycle
    
    -- splitList n = map (take n) . tails . cycle >>= zipWith const
    

    完成这项工作,也适用于无限输入,即适当的懒惰。

    使用zipWith const 代替lengthtake,计算列表元素而不是数字。

    无点变体甚至可以阅读/说明这里发生了什么。

    (忘了说,tails 来自Data.List)。

    【讨论】:

    • 我已经全部输入了。 :) 还是决定发布它,以获取无意义的内容。 :)
    猜你喜欢
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2020-04-09
    • 2013-12-05
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多