如何在Haskell中将列表分为两个?

4
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在尝试将一个列表分成两个部分,以便在输入为

[1,2,3,5,6]

输出将是:
[1,2,3][5,6] 

但我似乎无法弄清楚它。
我所能做的最好的就是[1,3,6][2,5]

1
你能发一下你已经写的代码吗?不知道你想要做什么,就无法指导你正确的方向。另外,你能再详细说明一下你的函数吗?如果输入的列表长度不同会怎样?分割列表的条件是什么? - bheklilr
3
Hoogle是你的好朋友。请访问以下链接:Hoogle搜索结果 - fjarri
1个回答

10

我是一个初学者。所以,如果有错误或不够优化的地方,请纠正我。

internalSplit :: [a] -> Int -> [a] -> [[a]]
split :: [a] -> [[a]]

internalSplit (first:rest) count firstPart
    | count == 0 = [firstPart, (first:rest)]
    | otherwise  = internalSplit rest (count - 1) (firstPart ++ [first])

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2) []
        else
            internalSplit myList ((listLength `div` 2) + 1) []

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

输出

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

编辑:

成功使用内置函数并得出以下结果:

internalSplit :: [a] -> Int -> [[a]]
split :: [a] -> [[a]]

internalSplit myList splitLength = [(take splitLength myList), (drop splitLength myList)]

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

输出

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

编辑1:

internalSplit :: [a] -> Int -> ([a], [a])
split :: [a] -> ([a], [a])

internalSplit myList splitLength = splitAt splitLength myList

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

输出

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

编辑2

正如Bogdon在评论部分所建议的那样,这可以大大简化为如下内容。

split :: [a] -> ([a], [a])
split myList = splitAt (((length myList) + 1) `div` 2) myList
main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

输出

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

7
为什么不使用 splitAt 呢?splitHalf l = splitAt ((length l + 1) `div` 2) l。 提示:splitAt 函数可以将列表分成两部分,第一个参数指定切割点的位置。 - fjarri
我在第二次编辑中使用了它,但不像你的那么简洁。谢谢 :) - thefourtheye
@Bogdan 我更新了我的答案,加入了这个解决方案。 - thefourtheye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接