尾递归切片函数的99个问题

时间:2017-09-22 18:27:00

标签: ocaml tail-recursion

99 Problems的第18个问题如下:

  

给定两个索引ik,切片是包含该索引的列表   原始列表的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;;

1 个答案:

答案 0 :(得分:4)

这实际上不是优雅而是复杂的问题。这可以在O(n)中实现,但你的解决方案是O(n²),这很糟糕。

确实将两个列表与@连接起来并不是一个恒定的时间操作。并且它也不是尾递归(see source code)。所以每个连接都是O(n),你做O(n),所以整体复杂度是O(n²)。