如何从ocaml列表中获取子列表

发布于 2024-08-30 22:57:14 字数 432 浏览 3 评论 0原文

我正在查看列表文档。该库似乎没有提供 sublist 功能。

我正在尝试获取从 ij 的元素列表。现在我必须将其写为:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请爱~陌生人 2024-09-06 22:57:14
let rec sublist b e l = 
  match l with
    [] -> failwith "sublist"
  | h :: t -> 
     let tail = if e=0 then [] else sublist (b-1) (e-1) t in
     if b>0 then tail else h :: tail
;;

sublist 3 5 [1;2;3;4;5;6;7;8;9] ;;
- : int list = [4; 5; 6]

以上或多或少是 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

let rec sublist b e l = 
  match l with
    [] -> failwith "sublist"
  | h :: t -> 
     let tail = if e=0 then [] else sublist (b-1) (e-1) t in
     if b>0 then tail else h :: tail
;;

sublist 3 5 [1;2;3;4;5;6;7;8;9] ;;
- : int list = [4; 5; 6]

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)) since List.filteri doesn't know that f only returns false after a while, it calls it for all elements in l.

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

拒绝两难 2024-09-06 22:57:14

首先尝试编写 take (前 n 个项目)和 drop (除了前 n 个项目之外的所有项目)函数(就像在 Haskell 中一样)。那么 sublist ij lst 只是 take (ji) (drop i lst)

Try writing the take (first n items) and drop (everything but the first n items) functions (like in Haskell) first. Then sublist i j lst is just take (j-i) (drop i lst)

锦爱 2024-09-06 22:57:14

这比使用 OCaml 的标准库要困难一些——标准库有点稀疏。如果您使用扩展标准库之一,它会变得更容易。例如,对于 Core,您可以这样写:

let sublist list low high =
   List.filteri l ~f:(fun i _ -> i >= low && pos < high)

我想 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:

let sublist list low high =
   List.filteri l ~f:(fun i _ -> i >= low && pos < high)

I imagine something similar is possible with extlib/batteries.

或十年 2024-09-06 22:57:14

虽然 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 the Array.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.

铁憨憨 2024-09-06 22:57:14
let rec sublist (lst : int list) (start : int) (stop : int) : int list =
  match lst with
  | [] -> [] 
  | x::rest when start = 0 && stop >= 0 -> x::sublist rest start (stop-1)
  | x::rest when start = 0 && stop = 0 -> sublist rest start stop
  | x::rest -> sublist rest (start-1) (stop-1)
;;

when 的作用与 if else 语句一样

let rec sublist (lst : int list) (start : int) (stop : int) : int list =
  match lst with
  | [] -> [] 
  | x::rest when start = 0 && stop >= 0 -> x::sublist rest start (stop-1)
  | x::rest when start = 0 && stop = 0 -> sublist rest start stop
  | x::rest -> sublist rest (start-1) (stop-1)
;;

when works as if else statement

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文