如何在Haskell中编写反向函数
所以,我知道,Haskell中有一个内置函数来反转列表,但我正在尝试编写自己的小函数,只是为了练习一些Haskell。我想到了下面的代码,可惜它不起作用。你们能告诉我我做错了什么吗如何在Haskell中编写反向函数,haskell,reverse,Haskell,Reverse,所以,我知道,Haskell中有一个内置函数来反转列表,但我正在尝试编写自己的小函数,只是为了练习一些Haskell。我想到了下面的代码,可惜它不起作用。你们能告诉我我做错了什么吗 rev :: [Int] -> [Int] rev [] = [] rev [x] = last [x] : rev init [x] 你差点就成功了 rev :: [Int] -> [Int] rev [] = [] rev x = last x : rev (init x)
rev :: [Int] -> [Int]
rev [] = []
rev [x] = last [x] : rev init [x]
你差点就成功了
rev :: [Int] -> [Int]
rev [] = []
rev x = last x : rev (init x)
说明:[x]是一个包含x的列表,而您希望直接使用x进行操作
还有,这是你的答案。请记住导入数据。列出您可以这样做:
rev :: [Int] -> [Int]
rev [] = []
rev (x:l) = (rev l) ++ [x]
第三行从列表中获取第一个元素,然后创建一个仅包含该元素的列表。这将附加到递归调用的结果中。如果您想有效地执行此操作,我建议您使用累加器:
rev :: [a] -> [a]
rev xs = go xs []
where
go :: [a] -> [a] -> [a]
go [] ys = ys
go (x:xs) ys = go xs (x:ys)
函数go
在每一步从第一个列表xs
中删除一个元素,并将其置于第二个列表ys
的前面。这类似于从一个堆栈弹出并推到另一个堆栈——这会颠倒顺序
由于我们在每次递归调用中只使用恒定的时间量,因此我们得到了O(n)复杂度,其中n是列表长度
相反,如果在每次递归调用中使用
last
或追加…++[x]
,我们为每个呼叫支付O(n),因此总体上为O(n^2)。[x]
是一个包含单个元素的列表(名为x
)last[x]
只是x
,而init[x]
是[]
。所以last[x]:revinit[x]
是x:rev[]
,它是x:[]
,它是[x]
。因此,您的最后一行相当于rev[x]=[x]
。但是你的主要问题是你没有一个包含多个元素的列表,这就是我要搜索的!谢谢!不客气!如果您觉得答案很好地回答了您的问题,请记住接受答案(单击绿色勾号)。我认为这甚至不能用let
进行解析:感谢您发现错误let
被删除。我认为这不是一个有效的reverse
函数,因为许多调用了昂贵的最后一个函数。我认为这是一种更好的工作方式。