|
16
|
| Matt Ellen Bipin Vayalu · 技术社区 · 16 年前 |
|
|
1
15
|
|
|
2
17
虽然它只处理列表中的元素一次(我的假设是计算
其思想是在列表中有两个“指针”,一个在递归的每个点上增加一个步骤,另一个增加两个步骤。 (这基本上就是卡尔·斯莫特里茨建议的) |
|
|
3
16
只是为了你的娱乐,一个不说哈斯克尔语的人的解决方案: 编写一个接收两个参数(A1和A2)的递归函数,并将列表作为两个参数传入。在每次递归中,从a2中删除2,从a1中删除1。如果你没有A2元素,你将处于A1元素的中间。您可以处理A2中只剩下1个元素的情况,以回答您的“中间”是否需要1或2个元素。 |
|
|
4
9
正确问题的正确数据结构。在这种情况下,您已经指定了一些仅在
有限的
名单,对吧?无限列表中没有“中间”项。因此,只要阅读描述,我们就知道默认的haskell列表可能不是最好的解决方案:即使我们不需要它,我们也可能为懒惰付出代价。注意有多少解决方案难以避免
幸运的是,我们在Haskell中确实有一个有限的列表:它被称为 Data.Sequence . 让我们用最明显的方法来解决这个问题:“索引(长度/2)”。
data.seq.length是
注意,即使我们不从
会更好,因为
(作为练习,我留给读者修改中间部分,如果长度为偶数,返回2项;如果长度为奇数,返回1项。毫无疑问,使用具有恒定时间长度和索引操作的数组可以做得更好,但我觉得数组不是一个列表。) |
|
|
5
5
Haskell解决方案灵感来自 Carl's answer .
|
|
|
6
2
如果序列是链表,则该链表的遍历是效率的主要因素。因为我们需要知道整个长度,所以我们必须至少遍历列表一次。有两种等效的方法来获取中间元素:
两者都需要相同数量的步骤。在我看来,第二个问题是不必要的复杂。 在哈斯克尔,可能是这样的:
|
|
|
7
1
此解决方案仅使用惰性计算遍历列表一次。当它遍历列表时,它计算长度,然后将其反馈给函数:
现在可以计算中间元素:
|
|
8
1
F基于Carl答案的解决方案:
修改列表中的中值元素也很容易:
更直观的方法是使用计数器:
以及一个非常丑陋的修改来得到中间元素:
获取列表的长度要求至少遍历其整个内容一次。幸运的是,编写自己的列表数据结构是非常容易的,它在每个节点中保存列表的长度,允许您以o(1)获取长度。 |
|
|
9
1
奇怪的是,这个非常明显的公式还没有出现:
|
|
|
10
0
一个非常直截了当,却又缺乏法律依据,而且不那么简单的解决方案可能是:
|
|
|
11
0
这将在列表上迭代两次。
|
|
|
12
0
虽然这个例子只适用于奇数列表,但我只为一行程序而活。我只是想舒展一下我的大脑!谢谢你的乐趣=)
|
|
|
13
0
我自己不是哈斯凯勒,但我试过这个。 首先测试(是的,可以使用haskell进行TDD)
我得出的解决方案是:
它将遍历列表两次,一次是为了获取长度,另一次是为了获取中间部分,但我不在乎它仍然是O(N)(获取中间部分意味着获取长度,所以没有理由避免它)。 |
|
|
14
0
我的解决方案,我喜欢保持简单:
使用
编辑:它现在实际工作了 |
|
|
15
0
我喜欢斯万特的回答。我的版本:
|
|
|
16
0
这是我的版本。这只是一个快速上升。我肯定不是很好。
我试过了。:) 如果有人想评论和告诉我这个解决方案有多糟糕或好,我会非常感激。我不是 非常 精通哈斯克尔。 编辑:根据KMC关于haskell blah的建议进行改进 编辑2:现在可以接受长度小于5的输入列表。 |
|
|
17
0
另一 一行 解决方案:
|