我正在查看List文档。似乎图书馆没有提供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),我宁愿以不那么简洁的方式写它。 / p>
我想知道为什么他们不提供List.sublist
func,如果List.nth
不是 O(1),因为这是一个非常常见的操作.. < / p>
答案 0 :(得分:10)
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(长度(长度)),因为List.filteri
不知道f
只在一段时间后返回false
,它会为l
中的所有元素调用它。
我不是很高兴让b
变为否定,但不是更复杂的版本。
如果您感兴趣,可以参考一些针对森林砍伐的文章:http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html
答案 1 :(得分:6)
首先尝试编写take
(前n项)和drop
(除前n项之外的所有项)函数(如Haskell中)。然后sublist i j lst
只是take (j-i) (drop i lst)
答案 2 :(得分:2)
这比使用OCaml的标准库要困难一点---标准库有点稀疏。如果您使用其中一个扩展标准库,则会更容易。例如,使用Core,您可以写:
let sublist list low high =
List.filteri l ~f:(fun i _ -> i >= low && pos < high)
我认为使用extlib / battery可以实现类似的功能。
答案 3 :(得分:0)
虽然Pascal提供的答案为Array.sub
实现了一个很好的候选者,但正确的答案是你应该更好地使用列表数组。 Array模块实现了您可能使用的$htmltop = "<html><head></head><body><ul>"
$htmlbottom = "</ul></body></html>"
$wpath = Get-ChildItem F:\@software\ -recurse
$outp = $wpath | Where-Object {$_.extension -eq ".wav" -and $_.name -like "*hou*"}
$outp = $outp | % { $("<li><a href='file://" + $($_.FullName) + "'>" + $($_.Name) + "</a></li>")}
$htmltop | Out-File F:\@software\htmlout99.html -Append
$outp | Out-File F:\@software\htmlout99.html -Append
$htmlbottom | Out-File F:\@software\htmlout99.html -Append
ii F:\@software\htmlout99.html
函数。
虽然在许多命令式语言(如C ++或Perl)中,列表和数组之间基本没有区别,但在OCaml中这是不同的:
列表更适合递归处理和顺序访问,即通常更适合作为数组作为递归函数的参数,你通常想看看所有列表的元素。
数组更适合随机访问,结构更改(如排序)或数值计算。