OCaml中string_to_list函数栈溢出,求其尾递归版本实现方案
OCaml string_to_list 尾递归实现方案
栈溢出原因
原实现属于非尾递归写法:每次递归调用loop后还需要执行字符拼接列表的::操作,无法触发OCaml的尾调用优化,调用栈深度会随输入字符串长度线性增长,输入超长时就会触发栈溢出错误。
尾递归实现
尾递归的核心是通过累积器参数传递中间计算结果,让递归调用成为函数执行的最后一步,编译器可复用当前栈帧,不会随递归深度增长占用额外栈空间。
版本1:正序遍历+结果反转
let string_to_list str = let rec loop i limit acc = if i = limit then List.rev acc else loop (i + 1) limit (String.get str i :: acc) in loop 0 (String.length str) [] ;;
逻辑说明:遍历过程中把当前字符追加到累积器acc头部,遍历完成后通过List.rev(本身也是尾递归实现)反转得到正序列表。
版本2:倒序遍历无需反转
let string_to_list str = let rec loop i acc = if i < 0 then acc else loop (i - 1) (String.get str i :: acc) in loop (String.length str - 1) [] ;;
逻辑说明:从字符串最后一位开始往前遍历,每次把当前字符追加到累积器头部,遍历完成后直接得到正序的字符列表,省略了反转步骤,性能更优。
内容的提问来源于stack exchange,提问作者Inbar
相关产品推荐
相关产品推荐

