List Haskell:列表操作
我想写一个函数,它接受一个输入列表,并按以下方式操作它: 步骤1:获取列表的第一个元素和列表的最后一个元素,并将其放在一个子列表中 步骤2:获取列表的第二个元素和列表的第二个最后一个元素,并将其放在下一个子列表中 步骤3:获取列表的第三个元素和 列出并将其放在下一个子列表中 根据相同的方案继续此操作(对于n个元素的列表) 如果输入列表的元素数为奇数,则输入列表的n/2元素将添加为输出列表的最后一个子列表 例如:List Haskell:列表操作,list,haskell,List,Haskell,我想写一个函数,它接受一个输入列表,并按以下方式操作它: 步骤1:获取列表的第一个元素和列表的最后一个元素,并将其放在一个子列表中 步骤2:获取列表的第二个元素和列表的第二个最后一个元素,并将其放在下一个子列表中 步骤3:获取列表的第三个元素和 列出并将其放在下一个子列表中 根据相同的方案继续此操作(对于n个元素的列表) 如果输入列表的元素数为奇数,则输入列表的n/2元素将添加为输出列表的最后一个子列表 例如: [1,2,3,4,5,6,7] -- should be transformed
[1,2,3,4,5,6,7]
-- should be transformed to
[[1,7],[2,6],[3,5],[4]]
我已经编写了一个函数,它接受列表中的每2个元素并将其放在子列表中,我想知道这段代码是否可以帮助我解决上述问题:
g2 :: [a] -> [[a]]
g2 [] = []
g2 (x1:x2:xs) = [x1,x2]: g2 xs
g2 xs = [xs]
请注意,我们必须在此处使用
drop 1
而不是tail
,以避免奇数长度列表的错误
g2 :: [a] -> [[a]]
g2 [] = []
g2 xs = [first xs] ++ (g2 . drop 1 $ init xs)
where first (x:[]) = [x]
first xs = [head xs, last xs]
请注意,我们必须在此处使用
drop 1
而不是tail
,以避免奇数长度列表的错误
g2 :: [a] -> [[a]]
g2 [] = []
g2 xs = [first xs] ++ (g2 . drop 1 $ init xs)
where first (x:[]) = [x]
first xs = [head xs, last xs]
这里有一个使用了
转置
import Data.List
g2 xs =
transpose [take (x + y) xs, take x (reverse xs)]
where (x, y) = (length xs) `divMod` 2
这里有一个使用了
转置
import Data.List
g2 xs =
transpose [take (x + y) xs, take x (reverse xs)]
where (x, y) = (length xs) `divMod` 2
这里有一个可以一次性完成:
对::[a]->[[a]]
配对xs=fst(go xs xs),其中
go(x:xs)(_::ys)=fx(go-xs-ys)
go(x:xs)[[u]=([x]],xs)
go xs[]=([],xs)
fx(xs,y:ys)=([x,y]:xs,ys)
它是如何工作的?让我们看一下go first的前两个参数,特别是这一行:
go(x:xs)(::ys)=fx(go-xs-ys)
这两个参数都来自同一个列表(xs
),但是我们从一个参数中删除了两项,并且只从另一个参数中删除了一项。为什么?所以我们知道当我们到达一半的时候。查看此函数以进行比较:
中途xs=go-xs-xs
哪里
go(:xs)(:ys)=go xs ys
goxs uxs=xs
>>>半途而废[1..6]
[4,5,6]
现在,一旦我们到了一半,我们需要用另一个列表“压缩”它。但它需要反过来!我们如何做到这一点?在一个过程中反转任何函数的一个简便方法是首先将其作为折叠写入。这里的拉链写为折叠:
zip=foldr(\xk(y:ys)->(x,y):kys)(常量[])
要“反转”它,您只需将其作为foldl
而不是foldr
(您还必须翻转闭包)
对于我们的使用,我们基本上是边走边建立基础(以k
的形式)。不,我们的函数如下所示:
对::[a]->[[a]]
pairs xs=go xs xs(const[]),其中
go(y:ys)(_::zs)k=go-ys-zs(f-y-k)
go(y:ys)[[u]k=[y]:kys
go ys[]k=k ys
fxk(y:ys)=[x,y]:kys——与“zip”中的“f”相同`
还有一个问题:列表返回的顺序错误。为了解决这个问题,我们将列表替换为,并交换附录的顺序
最后,我们取消CPS函数,得到上面的结果。这里有一个函数一次完成:
对::[a]->[[a]]
配对xs=fst(go xs xs),其中
go(x:xs)(_::ys)=fx(go-xs-ys)
go(x:xs)[[u]=([x]],xs)
go xs[]=([],xs)
fx(xs,y:ys)=([x,y]:xs,ys)
它是如何工作的?让我们看一下go first的前两个参数,特别是这一行:
go(x:xs)(::ys)=fx(go-xs-ys)
这两个参数都来自同一个列表(xs
),但是我们从一个参数中删除了两项,并且只从另一个参数中删除了一项。为什么?所以我们知道当我们到达一半的时候。查看此函数以进行比较:
中途xs=go-xs-xs
哪里
go(:xs)(:ys)=go xs ys
goxs uxs=xs
>>>半途而废[1..6]
[4,5,6]
现在,一旦我们到了一半,我们需要用另一个列表“压缩”它。但它需要反过来!我们如何做到这一点?在一个过程中反转任何函数的一个简便方法是首先将其作为折叠写入。这里的拉链写为折叠:
zip=foldr(\xk(y:ys)->(x,y):kys)(常量[])
要“反转”它,您只需将其作为foldl
而不是foldr
(您还必须翻转闭包)
对于我们的使用,我们基本上是边走边建立基础(以k
的形式)。不,我们的函数如下所示:
对::[a]->[[a]]
pairs xs=go xs xs(const[]),其中
go(y:ys)(_::zs)k=go-ys-zs(f-y-k)
go(y:ys)[[u]k=[y]:kys
go ys[]k=k ys
fxk(y:ys)=[x,y]:kys——与“zip”中的“f”相同`
还有一个问题:列表返回的顺序错误。为了解决这个问题,我们将列表替换为,并交换附录的顺序
最后,我们取消CPS函数,得到上面的结果。还有两个,第二个是使用:
pair xs=take(长度xs`div`2)$zip xs(反向xs)
--注意:使用元组而不是列表
导入数据。列表
pairs2=展开器(\xs->
如果长度xs<2
那就什么都没有了
else Just([head xs,last xs],init.tail$xs))
xs=[2,3,4,7,6]
对xs--[(2,6)、(3,7)]
pair2x--[[2,6],[3,7]]
还有两个,第二个是使用:
pair xs=take(长度xs`div`2)$zip xs(反向xs)
--注意:使用元组而不是列表
导入数据。列表
pairs2=展开器(\xs->
如果长度xs<2
那就什么都没有了
else Just([head xs,last xs],init.tail$xs))
xs=[2,3,4,7,6]
对xs--[(2,6)、(3,7)]
pair2x--[[2,6],[3,7]]
如果你不关心复杂性,你可以使用head
和last
函数:它们是O(n)。如果你不关心复杂性,你可以使用head
和last
函数:它们是O(n)。我正要发布一个非常类似的解决方案,但我使用了splitAt(length xs`div`2)xs
哦,很好,这甚至更好,我正要发布一个非常类似的解决方案,但我使用了splitAt(length xs`div`2)xs
哦,太好了