如何从ocaml列表中获取子列表
我正在查看列表文档。该库似乎没有提供 sublist
功能。
我正在尝试获取从 i 到 j 的元素列表。现在我必须将其写为:
let rec sublist list i j =
if i > j then
[]
else
(List.nth list i) :: (sublist list (i+1) j)
这非常简洁,但我质疑 List.nth
的效率,因为如果它是 O(n),我宁愿以不太简洁的方式编写它。
我想知道为什么他们不提供 List.sublist
函数,如果 List.nth
不是 O(1),因为它是这样的很常见的操作..
I'm looking at the List documentation. It seems the library does not provide a sublist
function.
I'm trying to get list of elements from i to j. Now I have to write it as:
let rec sublist list i j =
if i > j then
[]
else
(List.nth list i) :: (sublist list (i+1) j)
which is quite concise but I'm questioning the efficiency of List.nth
, because if it's O(n), I would rather have to write it in a less concise way.
I'm wondering why didn't they provide List.sublist
func, if List.nth
is not O(1), because it's such a quite common operation..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
以上或多或少是 newacct 解决方案的砍伐版本。 newacct 的解决方案分配一个中间列表(
drop i list
),编译器可以在 Haskell 中对其进行优化,但在 ML 中则困难得多。因此,他的版本非常适合 Haskell 函数,但对于 ML 函数来说稍显次优。两者之间的差别只是一个常数因子:都是 O(e)。 zrr 的版本是 O(length(l)),因为List.filteri
不知道f
仅在一段时间后返回false
,它调用它适用于l
中的所有元素。我不太高兴让
b
变为负数,但不这样做的版本更复杂。如果您有兴趣,可以从众多有关森林砍伐的参考文献中找到一份:http:// /homepages.inf.ed.ac.uk/wadler/topics/deforestation.html
The above is more or less a deforested version of newacct's solution. newacct's solution allocates an intermediate list (
drop i list
), which is possible for the compiler to optimize away in Haskell but much harder in ML. Therefore his version is perfectly fine for a Haskell function and marginally sub-optimal for an ML one. The difference between the two is only a constant factor: both are O(e). zrr's version is O(length(l)) sinceList.filteri
doesn't know thatf
only returnsfalse
after a while, it calls it for all elements inl
.I'm not very happy to let
b
go negative but the version where it doesn't is more complicated.One reference among quite a few for deforestation if you're interested: http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html
首先尝试编写
take
(前 n 个项目)和drop
(除了前 n 个项目之外的所有项目)函数(就像在 Haskell 中一样)。那么sublist ij lst
只是take (ji) (drop i lst)
Try writing the
take
(first n items) anddrop
(everything but the first n items) functions (like in Haskell) first. Thensublist i j lst
is justtake (j-i) (drop i lst)
这比使用 OCaml 的标准库要困难一些——标准库有点稀疏。如果您使用扩展标准库之一,它会变得更容易。例如,对于 Core,您可以这样写:
我想 extlib/batteries 也可以实现类似的功能。
This is a bit harder than it should be with OCaml's standard library --- the standard library is a bit sparse. If you use one of the extended standard libraries, it gets easier. With Core, for example, you could write:
I imagine something similar is possible with extlib/batteries.
虽然 Pascal 提供的答案实现了
List.sublist
的一个很好的候选者,但正确的答案是您应该更好地使用列表数组。 Array 模块实现了您可能使用的 Array.sub 函数。虽然在许多命令式语言(例如 C++ 或 Perl)中,列表和数组之间本质上没有区别,但在 OCaml 中却不同,其中:
列表更适合递归处理和顺序访问,即 通常是作为递归函数参数的数组的更好候选者,并且您通常希望查看列表的所有元素。
数组更适合随机访问、结构更改(例如排序)或数值计算。
数组
While the answer provided by Pascal implements a nice candidate for
List.sublist
the right answer is that you should probably better use an array of a list. The Array modules implements theArray.sub
function that you might use.While in many imperatives languages such as C++ or Perl there is essentially no difference between lists and arrays, this is not the same in OCaml where:
Lists are better suited for recursive treatments and sequential access, i.e. is usually a better candidate as an array as argument to a recursive function, and you usually want to take a look at all the elements of the list.
Arrays are better suited for random access, structure alteration (such as sorting), or for numerical computations.
when 的作用与 if else 语句一样
when works as if else statement