99 Problems的第18个问题如下:
给定两个索引
i
和k
,切片是包含该索引的列表 原始列表的i
'和k
'元素之间的元素(两者都有 限制包括)。开始用0计算元素(这就是方法List
模块编号元素。)
slice
函数应该表现得像:
# slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 2 6;;
- : string list = ["c"; "d"; "e"; "f"; "g"]
切片功能的我的版本(下面)比网站上提供的解决方案更简单(在我看来)。
你能确认它是尾递归的吗?
你能解释为什么99问题中提供的解决方案比下面的方案更优雅吗?
let slice list i k =
let rec sl i k acc = function
[] -> acc
|h::t -> if i > 0 then sl (i - 1) (k - 1) acc t else
if k > 0 then sl i (k - 1) (acc@[h]) t else
(acc@[h])
in sl i k [] list;;
答案 0 :(得分:4)
这实际上不是优雅而是复杂的问题。这可以在O(n)中实现,但你的解决方案是O(n²),这很糟糕。
确实将两个列表与@
连接起来并不是一个恒定的时间操作。并且它也不是尾递归(see source code)。所以每个连接都是O(n),你做O(n),所以整体复杂度是O(n²)。