我在试着把名单倒过来。
下面是我的代码:
reverseList :: [Int] -> [Int]
reverseList [] = []
reverseList (x:xs) = x:reverseList xs
最后发生的事情是我最终得到了相同顺序的列表。我甚至有一个解决方案,如何扭转列表,但我试图了解我在这里做错了什么?我是非常新的haskell所以认为我应该专注于了解更多,然后我可以轻松地解决更多的问题。我知道有很多解决这个问题的方法,但是我需要更多的帮助来理解,特别是我在这段代码中做错了什么。
7条答案
按热度按时间g6ll5ycj1#
在Haskell中有几种方法可以解决这个问题,最简单的方法是使用连接函数
++
:然而,这对于大型列表来说会非常慢,因为Haskell列表实际上是单向链表,所以为了追加一个元素,你必须遍历整个列表。另一种选择是在helper函数中跟上你正在构建的列表:
但是,这实际上只是
fold
模式:但是
\acc x -> x : acc
就是flip (:)
,所以可以写成然而,最简单的方法可能是在Prelude中使用
reverse
函数。我想指出的是,你的
reverseList :: [Int] -> [Int]
类型可以推广到:: [a] -> [a]
,你没有对列表的元素做任何特殊的处理,你只是用它们构建一个新的列表。g0czyy6m2#
你把列表分成头和尾,然后按照相同的顺序重新组合列表。以列表
[1, 2, 3]
为例:在第一次调用中,
x
将变为1
,xs
将变为[2, 3]
,然后创建一个新的列表,其中x
(因此为1)位于前面,reverseList [2, 3]
位于后面。0kjbasz63#
在Haskell中有几种方法可以解决这个问题。下面是一个带有cons和last/init的解决方案:
或使用foldl:
tyg4sfes4#
基本上是使用附加的简单算法
O(n(n-1)/2)~ O(n^2)的时间复杂度是O(n(n-1)/2)~ O(n^2)的时间复杂度是O(n(n-1)/2)~ O(n^2)的时间复杂度。
因此,对于这种附加繁重的任务,存在差异列表数据类型。
一个不同的列表就是一个用函数表示的列表。我的意思是,一个像
[1,2,3]
这样的列表,当用DList类型表示时,将是\xs -> [1,2,3] ++ xs
或简称为([1,2,3] ++)
这有点酷,因为DList是函数,我们可以通过组合(.)运算符将其追加,得到一个新的DList。换句话说,
toDList (xs ++ ys) == (toDList xs) . (toDList ys)
。这是一个复杂度为O(n)的问题,因为每一个函数组合都是O(1)的,所以它的时间复杂度为O(n),而每一个函数组合都是O(1)的。
现在我们已经在
DList a
类型中得到了反向的[a]
,我们需要应用fromDList
Difference List数据类型并不像上面所示的那么简单。它可以有Monoid、Functor和MonadT示例。有关这个有用数据类型的更多信息,请查看Data.DList
ctzwtxfj5#
简单。使用内置的
reverse
函数:wnavrhmk6#
在Haskell中,使用列表解析定义了反向函数。
bq8i3lrv7#
此反转功能与累加器和fold1一起工作。
这个使用递归。