【问题标题】:How to create a list from two list and the element from those list alternatively如何从两个列表和这些列表中的元素交替创建列表
【发布时间】:2017-01-22 23:36:43
【问题描述】:

我是 Haskell 的新手。我正在尝试使用递归来编写一个函数,给定两个列表(它们需要是相同的类型),交错它们的元素(在第一个和第二个列表之间交替使用元素)。当其中一个列表中没有更多元素时,它会停止,结果是列表达到了那么远。

interChange :: [a] -> [b] ->[(a,b)]
interChange _ [] = []
interChange [] _ = []
interChange (x:xs) (y:ys) =  (x,y) : interChange xs ys

我的输出示例:

interChange [1,2,3] [4,5,6]
 [(1,4),(2,5),(3,6)]

所需输出的示例是:

interChange [1,2,3] [4,5,6]
[1,4,2,5,3,6]

感谢您的帮助

【问题讨论】:

    标签: haskell recursion


    【解决方案1】:

    您的 interChange 与 Prelude 的 zip 相同。

    ghci> zip [1,2,3] ["wibble", "wobble", "wubble"]
    [(1,"wibble"),(2,"wobble"),(3,"wubble")]
    

    要编写您指定的函数,您实际上需要一对相同类型的列表。我们正在输出一个特定类型的列表,因此进入该列表的所有元素也必须具有该类型。

    interleave :: [a] -> [a] -> [a]
    

    您可以通过传递Bool 以递归方式实现此功能,指示您应该从哪个列表中获取下一个元素:

    interleave = go True
        where go _ [] ys = ys
              go _ xs [] = xs
              go True (x:xs) ys = x : go False xs ys
              go False xs (y:ys) = y : go True xs ys
    

    评估go 的最后两个子句之间的乒乓球,直到其中一个输入列表为空,然后我们只返回另一个输入列表的其余部分。 (如果您希望它的行为更像 zip,则可以通过在这些情况下返回 [] 而不是 xsys 来截断输出。)


    但我始终建议尽可能避免递归到更高级别的编程。我们可以把这个函数写成管道:

    1. 使用zip 配对输入列表的元素
    2. 将结果列表中的每个元组变成一个二元素列表:map (\(x, y) -> [x, y])
    3. 使用concat 展平生成的列表列表

    所以代码看起来像这样:

    interleave xs ys = concat $ map (\(x, y) -> [x, y]) $ zip xs ys
    

    我发现此代码比递归代码更容易理解,递归代码需要您对控制流进行推理 - 它只是一系列高级指令。

    顺便说一句,您可以通过将中间map 拖到concatzip 中来省略它:

    interleave xs ys = concatMap (\(x, y) -> [x, y]) $ zip xs ys
    interleave xs ys = concat $ zipWith (\(x, y) -> [x, y]) xs ys
    

    【讨论】:

    • 非常感谢您的重播,您的代码非常好。但是,它不满足最后一个条件。当其中一个列表中没有更多元素时,它会停止。您的代码给出如下输出:[1,2,3,4] [6,7,8]= [1,6,2,7,3 ,8,4],但应该是 [1,6,2,7,3,8]
    • 我相信你可以弄清楚如何修改代码以适应练习。
    【解决方案2】:

    当使用两个非空列表(x:xs)(y:ys) 调用interChange 时,输出应该是一个以x 开头的列表,然后是y,然后是更多内容。所以你应该写类似

    interChange (x:xs) (y:ys) =  x : y : ...
    

    【讨论】:

      猜你喜欢
      • 2021-05-07
      • 2012-01-18
      • 2022-12-08
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 1970-01-01
      • 2015-04-29
      相关资源
      最近更新 更多