Haskell 从列表中获取可变数量的元素
我想创建一个函数,它返回将列表拆分为两个非空部分的所有可能方法的列表Haskell 从列表中获取可变数量的元素,haskell,lambda,Haskell,Lambda,我想创建一个函数,它返回将列表拆分为两个非空部分的所有可能方法的列表 split :: [([a], [a])] 例如: > split [1,2,3,4] > [ ([1], [2,3,4]), ([1,2], [3,4]), ([1,2,3], [4]) ] 我离解决方案还很远。有人能帮我吗?当然,使用地图、拆分和翻转很容易 首先要导入数据 结果: split [1,2,3,4] [([1],[2,3,4]),([1,2],[3,4]),([1,2,3],[4])] fl
split :: [([a], [a])]
例如:
> split [1,2,3,4]
> [ ([1], [2,3,4]), ([1,2], [3,4]), ([1,2,3], [4]) ]
我离解决方案还很远。有人能帮我吗?当然,使用地图、拆分和翻转很容易
首先要导入数据
结果:
split [1,2,3,4]
[([1],[2,3,4]),([1,2],[3,4]),([1,2,3],[4])]
flip的解释-在本例中,我们使用map和flip生成结果
[splitAt 1 x, splitAt 2 x, splitAt 3 x]
Flip只允许我们翻转预期参数。否则我们就可以这样写一个lambda:
let split x = map (\z -> splitAt z x) [1..length x-1]
下面是使用inits和tails的另一种方法: 设xs=[1,2,3,4]。注:
import Data.List
inits xs -- returns: [[] , [1], [1,2], [1,2,3], [1,2,3,4]]
tails xs -- returns: [[1,2,3,4], [2,3,4], [3,4], [4] , []]
因此,将这两个列表压缩在一起可以提供将列表分为两部分的所有方法:
zip (inits xs) (tails xs)
= [ ([], [1,2,3,4]),
([1], [2,3,4] ),
([1,2], [3,4]) ,
([1,2,3,4], []) ]
如果不需要第一对和最后一对,只需适当修剪:
split xs = init $ tail $ zip (inits xs) (tails xs)
如果您想自己实现它,而不是使用库函数
splits :: [a] -> [([a],[a])]
splits [] = []
splits xx = splits' ([],xx)
where splits' :: ([a],[a]) -> [([a],[a])]
splits' xy@(x,[]) = [xy]
splits' xy@(x,y:yy) = let z = (x++[y],yy)
in xy:splits' z
迭代的另一种方法
split (x:xs) = takeWhile (not . null . snd) $ iterate (\(x,(y:ys)) -> (x++[y],ys)) ([x], xs)
谢谢!我没有想到这个快速的解决方案!再次感谢!您也可以使用中缀splitAt而不是flip splitAt x。最好提及对数据执行类似操作。序列非常节省时间和空间,感谢Louis Wasserman出色的inits和tails实现,并在较小程度上感谢我自己的zip/zip实现。@dfeuer为什么它惊人地节省时间和空间-我认为Data.Sequence非常适合解决此类问题。@epsilonhalbe,它的inits和tails继续给我留下深刻印象。
split (x:xs) = takeWhile (not . null . snd) $ iterate (\(x,(y:ys)) -> (x++[y],ys)) ([x], xs)